线程状态转换图
新建(NEW):新建线程对象,未调用 start 方法
可运行(RUNNABLE):线程对象创建后,被调用 start 方法。此状态的线程位于可运行线程池中,等待获取 CPU 的使用权
运行中(RUNNING):线程获取了 CPU 的使用权,执行程序代码
阻塞(BLOCKED):线程因为某种原因放弃了 CPU 的使用权,暂时停止运行,直到线程进入可运行状态,才有机会再次获取 CPU 的使用权进入运行状态
消亡(DEAD):线程已经执行完毕。主线程 main 方法结束或因异常退出;子线程 run 方法结束或因异常退出
线程常见函数 | 来源类 | 是否 Static | 说明 | 是否释放锁 |
sleep() | Thread | static | 只能操作当前线程。时间到后(没有interrupt的情况下),回到“就绪”状态 | 不 |
yield() | Thread | static | 只能操作当前线程。只让出CPU时间片。不让出持有的锁和其他资源(磁盘IO,内存) | 不 |
join() | Thread | no | 在线程 B 中调用了线程 A 的 Join()方法,直到线程 A 执行完毕后,才会继续 执行线程 B | ? |
interrupt() | Thread | no |
可以在A 线程里调用B.interrupt(),只是将B线程的interrupted标志位置为true。
|
? |
interrupted() | Thread | static | 只能操作当前线程。会判断当前线程的interrupted状态,并且会重置该状态为false. | ? |
isInterrupted() | Thread | no | 可以在A 线程里调用B.isInterrupted().只是返回被检查线程的标志位情况,不会重置。 | ? |
wait() | Object | no |
针对某一个对象调用:object.wait().
|
是 |
notify()/notifyAll() | Object | no |
针对某一个对象调用:object.notify()
|
不 (执行完同步代码块才会释放) |
yield()
只让出CPU时间片。持有的锁,还有其他资源(磁盘IO,内存)不让出
- 使当前线程让出 CPU 占有权,但让出的时间是不可设定的。
- 也不会释放锁资源。注意:并不是每个线程都需要这个锁的,而且执行 yield( )的线 程不一定就会持有锁,我们完全可以在释放锁后再调用 yield 方法。
- 所有执行 yield()的线程有可能在进入到就绪状态后会被操作系统再次选中,马上又被执行。
join()
此处为常见面试考点
Q: 如何将多线程变为串行? A: 使用join()方法
把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行。
比如在线程 B 中调用了线程 A 的 Join()方法,直到线程 A 执行完毕后,才会继续 执行线程 B。
线程的优先级
在 Java 线程中,通过一个整型成员变量 priority 来控制优先级,优先级的范 围从 1~10,在线程构建的时候可以通过 setPriority(int)方法来修改优先级,默认 优先级是 5,优先级高的线程分配时间片的数量要多于优先级低的线程。
设置线程优先级时,针对频繁阻塞(休眠或者 I/O 操作)的线程需要设置较 高优先级,而偏重计算(需要较多 CPU 时间或者偏运算)的线程则设置较低的 优先级,确保处理器不会被独占。在不同的 JVM 以及操作系统上,线程规划会 存在差异,有些操作系统甚至会忽略对线程优先级的设定。