一、java线程的几种状态
状态 | 释义 |
---|---|
NEW | 一个创建了但还没有开始启动的线程 |
RUNNABLE | 线程start后变为可执行状态,具体是否执行取决于系统cpu调度 |
BLOCKED | 阻塞,等待锁,比如等待进入synchronized代码块 |
WAITING | 线程里调用了wait/join等方法后进入等待状态 |
TIMED_WAITING | 超时等待,类似WAITING,但是有时间限制,时间到了,自动进入RUNNABLE状态 |
TERMINATED | 结束 |
以上六种状态在Thread类中的内部枚举类State中有定义。
二、差异对比
方法 | 归属类 | 方法定义 | |
---|---|---|---|
sleep | Thread | public static native void | 线程休眠,休眠期间不占用cpu |
yield | Thread | public static native void | 让出当次cpu的执行权 |
wait | Object | public final native void | 线程等待,并释放拥有的对象锁 |
notify/notifyAll | Object | public final native void | 唤醒等待当前锁的其它线程 |
join | Thread | public final synchronized void | 线程等待,释放锁,并等待其它拥有该锁的线程执行结束 |
三、详细介绍
几个方法对应的线程状态图如下所示:
1、sleep
当前线程调用Thread.sleep(1000)陷入休眠,进入TIMED_WAITING状态,同时系统内核中会根据sleep中的参数设置一个定时器,定时器倒计时结束后,内核会重新唤醒线程,线程状态进入RUNNABLE状态;
2、yield
上面说到,线程状态在RUNNABLE状态下,由系统cpu决定是否执行,所以该状态下,线程在内核中实际有“运行中”和“就绪”两种状态,当前线程在“运行中”时,调用Thread.yield(),会立即让出cpu的使用权,让cpu执行优先级更高的或其它同优先级的线程,线程从RUNNABLE状态下的“运行中”变为“就绪”。
3、wait
当前线程获取Object锁后,调用Object的wait方法,则会使当前线程进入WAITING或TIMED_WAITING状态,并释放Object的持有锁,当前线程会被放入等待队列中,直到超时或者被其他线程调用锁对象的notify方法唤醒。
5、notify/notifyAll
当前线程获取Object锁后,调用Object的notify/notifyAll方法,会使此前调用了该Object的wait线程从WAITING状态进入RUNNABLE状态,notify只会唤醒一个线程,而notifyAll方法可以唤醒所有线程。
6、join
内部其实就是wait方法,不同于wait的是,它会主动等使用了Object的锁对象的线程彻底执行结束后,自动从WAITING状态进入RUNNABLE状态。