线程生命状态说明
Thread.State是一个内部枚举类,定义了6个枚举常量,分别代表Java线程的6种状态:
代码语言:javascript复制public static enum State { NEW, //新建 RUNNABLE, //可执行:包含操作系统的就绪、运行两种状态 BLOCKED, //阻塞 WAITING, //等待 TIMED_WAITING, //限时等待 TERMINATED; //终止}
NEW状态:创建成功但是没有调用start()方法启动的Thread线程实例都处于NEW状态。
TIMED_WAITING状态:线程处于一种特殊的等待状态,准确地说,线程处于限时等待状态
(1)Thread.sleep(int n):使得当前线程进入限时等待状态,等待时间为n毫秒。
(2)Object.wait():带时限的抢占对象的monitor锁。
(3)Thread.join():带时限的线程合并。
(4)LockSupport.parkNanos():让线程等待,时间以纳秒为单位。
(5)LockSupport.parkUntil():让线程等待,时间可以灵活设置。
Thread.yield()方法作用是:暂停当前正在执行的线程对象(及放弃当前拥有的cup资源), 并执行其他线程。yield()做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其 他线程获得运行机会。因此使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。
NEW:毫无疑问表示的是刚创建的线程,还没有开始启动。
RUNNABLE: 表示线程已经触发start()方式调用,线程正式启动,线程处于运行中状态。
BLOCKED:表示线程阻塞,等待获取锁,如碰到synchronized、lock等关键字等占用临界区的情况,一旦获取到锁就进行RUNNABLE状态继续运行。
WAITING:表示线程处于无限制等待状态,等待一个特殊的事件来重新唤醒,如通过wait()方法进行等待的线程等待一个notify()或者notifyAll()方法,通过join()方法进行等待的线程等待目标线程运行结束而唤醒,一旦通过相关事件唤醒线程,线程就进入了RUNNABLE状态继续运行。
TIMED_WAITING:表示线程进入了一个有时限的等待,如sleep(3000),等待3秒后线程重新进行RUNNABLE状态继续运行。
TERMINATED:表示线程执行完毕后,进行终止状态。
需要注意的是,一旦线程通过start方法启动后就再也不能回到初始NEW状态,线程终止后也不能再回到RUNNABLE状态。
线程状态切换详细说明
NEW状态
通过new Thread(…)已经创建线程,但尚未调用start()启动线程,该线程处于NEW(新建)状态。虽然前面介绍了4种方式创建线程,但是其中的其他三种方式本质上都是通过new Thread()创建线程,仅仅是创建了不同的target执行目标实例(如Runnable实例)。
RUNNABLE状态
Java把Ready(就绪)和Running(执行)两种状态合并为一种状态:RUNNABLE(可执行)状态(或者可运行状态)。调用了线程的start()实例方法后,线程就处于就绪状态。此线程获取到CPU时间片后,开始执行run()方法中的业务代码,线程处于执行状态。
就绪状态
就绪状态仅仅表示线程具备运行资格,如果没有被操作系统的调度程序挑选中,线程就永远处于就绪状态。当前线程进入就绪状态的条件大致包括以下几种:
·调用线程的start()方法,此线程就会进入就绪状态。
·当前线程的执行时间片用完。
·线程睡眠(Sleep)操作结束。
·对其他线程合入(Join)操作结束。
·等待用户输入结束。
·线程争抢到对象锁(Object Monitor)。
·当前线程调用了yield()方法出让CPU执行权限。
执行状态
线程调度程序从就绪状态的线程中选择一个线程,被选中的线程状态将变成执行状态。这也是线程进入执行状态的唯一方式。
BLOCKED状态
处于BLOCKED(阻塞)状态的线程并不会占用CPU资源,以下情况会让线程进入阻塞状态:
(1)线程等待获取锁
等待获取一个锁,而该锁被其他线程持有,则该线程进入阻塞状态。当其他线程释放了该锁,并且线程调度器允许该线程持有该锁时,该线程退出阻塞状态。
(2)IO阻塞
线程发起了一个阻塞式IO操作后,如果不具备IO操作的条件,线程就会进入阻塞状态。IO包括磁盘IO、网络IO等。IO阻塞的一个简单例子:线程等待用户输入内容后继续执行。
WAITING状态
处于WAITING(无限期等待)状态的线程不会被分配CPU时间片,需要被其他线程显式地唤醒,才会进入就绪状态。线程调用以下3种方法会让自己进入无限等待状态:
·Object.wait()方法,对应的唤醒方式为:
·Object.notify()/Object.notifyAll()。
·Thread.join()方法,对应的唤醒方式为:被合入的线程执行完毕。
·LockSupport.park()方法,对应的唤醒方式为:
·LockSupport.unpark(Thread)。
TIMED_WAITING状态
处于TIMED_WAITING(限时等待)状态的线程不会被分配CPU时间片,如果指定时间之内没有被唤醒,限时等待的线程会被系统自动唤醒,进入就绪状态。以下3种方法会让线程进入限时等待状态:
·Thread.sleep(time)方法,对应的唤醒方式为:sleep睡眠时间结束。
·Object.wait(time)方法,对应的唤醒方式为:调用
·Object.notify()/Object.notifyAll()主动唤醒,或者限时结束。
·LockSupport.parkNanos(time)/parkUntil(time)方法,对应的唤醒方式
为:线程调用配套的LockSupport.unpark(Thread)方法结束,或者线程停止(park)时限结束。
进入BLOCKED状态、WAITING状态、TIMED_WAITING状态的线程都会让出CPU的使用权;另外,等待或者阻塞状态的线程被唤醒后,进入Ready状态,需要重新获取时间片才能接着运行。
TERMINATED状态
线程结束任务之后,将会正常进入TERMINATED(死亡)状态;或者说在线程执行过程中发生了异常(而没有被处理),也会导致线程进入死亡状态。