1 创建线程与创建线程运行时代码
在Java中,创建线程的方式只有一种,就是创建Thread对象的实例。创建线程运行时代码
有三种方式:
第一种:继承Thread
类,覆写其run
方法。
第二种:实现Runnable
接口,实现run
方法,Thread类也实现了Runable接口。
第三种:实现Callable
接口,实现其call
方法,这种方式是在JDK1.5中的java并发包中引入的。
2 start()方法与run()方法的区别
start
()方法用于启动线程,start方法调用之后,线程进入可运行状态,一旦线程调度程序调度执行,线程即进入运行状态,线程启动后JVM才会给线程分配相应的资源,例如栈内存空间。然后回调线程运行时代码。
run
()方法用于执行线程的运行时代码,如果直接调用该方法并没有创建新的线程而是在当前线程中被执行。
3 覆盖了Thread对象的run方法,同时传入一个Runnable的实现类?
我们知道线程创建完成之后,然后JVM回调线程运行时代码run(),
所以查看Thread的默认run()
实现:
/* What will be run. */ private Runnable target; .... @Override public void run() { if (target != null) { target.run(); } }
其中target就是Runable对象,默认的run方法的逻辑是,如果传递了Runnable的实现类,就运行Runnable的run方法。故:当覆盖了Thread对象的run方法之后,执行的肯定是覆盖之后的逻辑,原来的这段逻辑如果不存在了,
就算传入了Runnable的实现类,也不会执行。
4 sleep()方法与wait()方法的区别
sleep()方法是Thread类中定义的静态方法,作用是让当前线程进行休眠暂停执行,在休眠期间线程不会请求CPU执行,因此其他线程(甚至更低优先级的线程)可以获得更多的运行机会。但是如果持有同步锁,并不会释放锁。
sleep方法有InterruptedException编译时异常需要捕获。并且不能指定休眠某一特定的线程t.sleep(),它只会是使当前线程被sleep 而不是t线程,所以即使t.sleep(...)这样调用,被暂停的也不是t线程而是当前线程,正确的用法应该是Thread.sleep(...)。调用sleep方法,线程进入到阻塞状态并不释放所占有的资源,sleep方法结束返回之后,线程重新回到可运行状态,而不是运行状态,需要线程调度机制重新恢复其到运行状态。
另外,java.util.concurrent.TimeUnit类的提供了语义更明确的sleep封装实现,其底层还是调用了Thread.sleep(...)方法,只是其单位更明确,例如休眠2秒钟:TimeUnit.SECONDS.sleep(2);
wait()方法是Object类中定义的方法,只能在同步方法或者同步代码块中调用,如果持有同步锁,会释放锁,让其他需要获得该锁的线程有机会运行。当线程调用wait()方法后会进入等待队列(进入这个状态会释放所占有的所有资源,与阻塞状态不同)
wait方法同样也可以在wait期间因为被其他对象调用interrupt()方法二产生InterruptedException运行时异常。一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程。调用wait或者notify的时候,当前线程必须要是对象lock的拥有者,否则会抛出IllegalMonitorStateException异常。
synchronized (share) { share.wait(); }
当线程在synchronized中调用了share.wait()时,在放弃了CPU的同时,也放弃了share这个对象的lock,进入这个对象的wait pool。
当另外一个线程调用了share.notify()时,将从wait pool中拿出一个线程,让该线程获得lock,并进入可运行状态,等待线程调度执行。
这也就是为什么wait/notify需要加锁的原因。
5 线程挂起与恢复suspend/resume
suspend可以将正在执行的线程挂起暂停执行。resume即使线程从挂起状态恢复。但这两个 API 是过期的,也就是不建议使用的。因为suspend()方法在执行时不会释放线程占用的资源(比如同步锁),并且没有超时时间的设定,如果resume在suspend之前调用或者在同步块内部执行,并且同步锁已经被挂起的线程占用,那么将陷入死锁状态。对于被挂起的线程,使用jconsole查看它的线程状态居然还是 Runnable。
另外,System.out.println(...)也是一个同步方法, 在执行打印之前需要获取PrintStream对象锁。并且PrintStream的实例对象out是System类的一个静态实例,System类中只有唯一的一个PrintOut对象:
public void println(String x) { synchronized (this) { print(x); newLine(); } }
所以下面的代码将永远无法打印出“main end!“,因为挂起的thread线程占用了PrintStream对象锁---out.
public class MyThread extends Thread{ private long i = 0; @Override public void run() { while (true) { i++; System.out.println(i);//同步方法 } } public static void main(String[] args) throws Exception{ MyThread thread = new MyThread(); thread.start();//启动一个线程'thread' Thread.sleep(1000l);//使当前线程(main线程)睡眠 thread.suspend();//挂起线程'thread' System.out.println("main end!"); } }
相关推荐
第二章 Java线程API 通过Thread类创建线程 使用Runable接口的线程 线程的生命周期 线程命名 访问线程 线程的启动、停止和连接 总结 第三章 同步技术 银行的例子 异步读取数据 一个进行同步操作的类 同步块 嵌套锁...
javax.imageio.spi 包含用于 reader、writer、transcoder 和流的插件接口以及一个运行时注册表的 Java Image I/O API 包。 javax.imageio.stream Java Image I/O API 的一个包,用来处理从文件和流中产生的低级别 I...
javax.imageio.spi 包含用于 reader、writer、transcoder 和流的插件接口以及一个运行时注册表的 Java Image I/O API 包。 javax.imageio.stream Java Image I/O API 的一个包,用来处理从文件和流中产生的低级别 I/...
javax.imageio.spi 包含用于 reader、writer、transcoder 和流的插件接口以及一个运行时注册表的 Java Image I/O API 包。 javax.imageio.stream Java Image I/O API 的一个包,用来处理从文件和流中产生的低级别 I...
javax.imageio.spi 包含用于 reader、writer、transcoder 和流的插件接口以及一个运行时注册表的 Java Image I/O API 包。 javax.imageio.stream Java Image I/O API 的一个包,用来处理从文件和流中产生的低级别 I/...
1996年1月,Java的第一个开发包JDK1.0发布。 Java历史网站 Java语言特点 Java极其流行,其设计特性:“一次编译,到处运行”。 简单性(simple) 面向对象(object oriented) 分布式(distributed) 解释型...
一个用于 Java 的简约多线程爬虫 API。 分散其简约的结构,此爬虫基于 Java ForkJoin 框架,该框架允许 RexCrawler 通过将其本地工作负载分区来按需创建其他守护进程。 这种方法的一个关键好处是更好地控制粒度和更...
1.6 Java线程 1.7 Java 5.0多线程编程 1.8 Java Socket编程 1.9 Java的内存泄漏 1.10 抽象类与接口的区别 1.11 Java变量类型间的相互转换 2 JAVA与WEB 2.1 JMX规范 2.1.1 JMX概述 2.1.2 设备层(Instrumentation ...
javax.imageio.spi 包含用于 reader、writer、transcoder 和流的插件接口以及一个运行时注册表的 Java Image I/O API 包。 javax.imageio.stream Java Image I/O API 的一个包,用来处理从文件和流中产生的低级别 I...
javax.imageio.spi 包含用于 reader、writer、transcoder 和流的插件接口以及一个运行时注册表的 Java Image I/O API 包。 javax.imageio.stream Java Image I/O API 的一个包,用来处理从文件和流中产生的低级别 I...
Java Thread API 允许程序员编写具有多处理机制优点的应用程序,在后台处理任务的同时保持用户所需的交互感。Alex Roetter 介绍了 Java Thread API,并概述多线程可能引起的问题以及常见问题的解决方案。
一、 Java概述 3 二、 Java语法基础 5 数据类型 5 运算符号 14 语句 15 函数 15 方法重载(Overloadjing)与重写(Overriding) 16 数组 17 总结 18 三、 常见关键字 20 四、 面向对象★★★★★ 21 五、 封装(面向...
Java语言基础 Java网络编程技术 Java程序设计使用教程 第01章 java语言概述(共43页).ppt Java语言基础 Java网络编程技术 Java程序设计使用教程 第02章 java语言基础(共112页).ppt Java语言基础 Java网络编程技术...
javax.imageio.spi 包含用于 reader、writer、transcoder 和流的插件接口以及一个运行时注册表的 Java Image I/O API 包。 javax.imageio.stream Java Image I/O API 的一个包,用来处理从文件和流中产生的低级别 I/...
【完整课程列表】Java语言基础 Java网络编程技术 Java程序设计使用教程 第01章 java语言概述(共43页).pptJava语言基础 Java网络编程技术 Java程序设计使用教程 第02章 java语言基础(共112页).pptJava语言基础 ...
1.6 Java线程 60 1.7 Java 5.0多线程编程 65 1.8 Java Socket编程 80 1.9 Java的内存泄漏 85 1.10 抽象类与接口的区别 86 1.11 Java变量类型间的相互转换 87 2 JAVA与WEB 87 2.1 JMX规范 87 2.1.1 JMX概述 87 2.1.2 ...