线程状态
线程的六种状态
通过查询Thread.Stat中定义的Enum名我们可以查询到线程一共有下面六种状态
1.初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
2.运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
3.阻塞(BLOCKED):表示线程阻塞于锁。
4.等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
5.超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
6.终止(TERMINATED):表示该线程已经执行完毕。
NEW新建状态
NEW是一个线程已被创建出来(new Thread)但未被启动的状态(start)。调用start()后线程就会进入RUNNABLE状态
RUNNABLE运行状态
RUNNABLE对应着操作系统中线程状态的:Running和Ready即运行态和就绪态。
一个线程如果正在执行任务到一半,这时它的CPU资源被调度给其他线程。这时线程会暂停但是它的状态还是RUNNABLE.
BlOCKED阻塞状态
从RUNNABLE进入BLOCKED状态只有一种可能,也就是进入synchronized保护的代码中而没有得到monitor锁。而当线程得到monitor锁后就会从BLOCKED转回RUNNABLE态
WAITING等待状态
线程进入WAITING有三种可能
1、使用没有设置Timeout参数的wait()方法
2、使用没有设置Timeout参数的join()方法
3、使用LockSupport.park()方法
Blocked和Wating的区别有两点:
1、Blocked只有针对synchronized锁(monitor锁)的情况而其他锁的情况会变为Waiting状态
2、Blocked状态是在等待其他线程释放monitor锁而Wating则是等待其他外部条件(例如notify/notifyAll或者join线程执行完毕)
TIMED_WATING超时等待状态
国内很多书本将其翻译为超时等待。其实更正确的翻译应该是限期/限时等待
此状态与Waiting的区别只是有没有等待时间限制。
Timed_Waitng有一个等待超时时间,超过这个时间会由系统自动唤醒线程(当然也是可以得到外部条件被唤醒)
进入情况其实与Waiting方法相对应
1、使用设置了Timeout参数的wait()方法
2、使用设置了Timeout参数的join()方法
3、使用设置了时间参数的LockSupport.parkNanos()方法
4、使用了sleep(long millis)方法
TERMINATED终止状态
这个状态没什么好说的进入的情况无非是两种:
1、线程运行结束
2、线程遇到未知异常而终止
状态转化的注意点
Waiting和Timed_Waiting状态如果是被notify和notifyAll通知过后是转换为Blocked而不是Runnable
原因是调用notify和notifyAll的线程按照规定一定要持有对应对象的monitor锁而使用wait方法进入Waiting和Timed_Waiting状态也是要求持有monitor锁,这意味着被唤醒线程要争抢来通知的线程此时持有的锁。所以会进入Blocked态。
Timed_Waiting态同理。