一、线程的五种状态及相互转换条件
从操作系统的角度,线程分为就绪、运行和阻塞三种状态。
线程的生命周期
创建:一个新的线程被创建,等待该线程被调用执行;
就绪:时间片已用完,此线程被强制暂停,等待下一个属于它的时间片到来;
运行:此线程正在执行,正在占用时间片;
阻塞:也叫等待状态,等待某一事件(如IO或另一个线程)执行完;
退出:一个线程完成任务或者其他终止条件发生,该线程终止进入退出状态,退出状态释放该线程所分配的资源。
java中定义了线程的六种状态:
public enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,//无限等待-直到线程终结或线程被唤醒
TIMED_WAITING,//超时等待 到指定时间后线程自动被唤醒
TERMINATED;//线程终止-正常结束和异常被终止
}
新建(New)
线程创建后尚未启动。
可运行(Runnable)
一旦调用了线程的start()方法,线程就处于可运行状态。可运行状态的线程可能正在运行,也可能还没有运行而正在等待 CPU 时间片。(Java规范中并没有分为可运行状态和正在运行状态这两个状态,而是把它们合为一个状态。所以,可以把一个正在运行中的线程仍然称其处于可运行状态。)
阻塞(Blocked)
处于阻塞状态的线程并不会占用CPU资源。
以下情况会让线程进入阻塞状态:
①等待获取锁
等待获取锁分为两种情形:1、在对象锁等待池 2、在对象锁池 在对象锁池的同志可以竞争对象锁 在对象锁等待池的同志就需要先被调度到等待锁池了。。。。。。
等待获取一个锁,而该锁被其它线程持有,则该线程进入阻塞状态。当其它线程释放了该锁,并且线程调度器允许该线程持有该锁时,该线程退出阻塞状态。
②IO阻塞
线程发起了一个阻塞式IO后也会进入阻塞状态。最典型的场景,如等待用户输入内容然后继续执行。
无限期等待(Waiting)-需要唤醒
处于这种状态的线程不会被分配 CPU 时间片,需要等待其它线程显式地唤醒。
以下方法会让线程进入无限期的等待状态
- Object.wait() 方法 结束:Object.notify() / Object.not