Java 中的线程状态,与操作系统中的线程状态略有不同,需要仔细记忆理解。
线程状态转换
New
通过new Thread()创建线程,创建后并未运行
Runnable (可运行状态)
- New状态,调用
start()
后,进入Runnable 状态。 - 注意:可能正在运行,也可能正在等待CPU时间片。
- 该状态对应操作系统中的Running 和Ready 两个状态
- 调用Thread,yield(),就是再上面所说的Running - > Ready。该操作由系统来支持
Blocked (阻塞状态)
阻塞状态是线程阻塞在进入synchronized关键字
修饰的方法或代码块(获取锁)时的状态。
Waiting & Time Waiting (等待 & 有限等待状态)
无限等待状态
与有限等待状态
,有点区别。这里为了方便自我记忆,写在一起。该状态中的线程,被加入等待队列,等待被显示的唤醒,不然不会分配CPU时间片。
这点是相同的,只是Time Waiting,有时间上的设置,在规定时间内,还没有被显示唤醒,也会被系统唤醒。
调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) 代码段内。
-
无线等待状态
进入条件 退出条件 没有设置 Timeout 参数的 Object.wait() 方法 Object.notify() /Object.notifyAll() 没有设置 Timeout 参数的 Object.join() 方法 等待目标线程执行完毕 -
有限等待状态
进入条件 退出条件 Thread.sleep() 方法 时间结束 设置了 Timeout 参数的 Object.wait() 方法 时间结束 / Object.notify() / Object.notifyAll() 设置了 Timeout 参数的 Thread.join() 方法 时间结束 / 被调用的线程执行完毕 LockSupport.parkNanos() 方法 - LockSupport.parkUntil() 方法 -
Terminated(死亡)
可以是线程结束任务之后自己结束,或者产生了异常而结束。
在一个终止的线程上调用start()
方法,会抛出java.lang.IllegalThreadStateException
异常。线程一旦终止了,就不能复生。
等待队列 & 同步队列
简单提一下,记录个人理解。
- 等待队列,等待被唤醒的线程队列。比如Object.wait() 后,就会加入该队列。
- 同步队列,争夺锁的线程队列,比如执行到Synchronized处,阻塞等待锁资源(排它锁),加入该队列。
- 当等待队列的线程被唤醒后(Object.notify() / Object.notifyAll()),就会加入该队列,一般来说,
一个锁对应一个同步队列。