「Java」Java线程的五种状态

这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战

image.png

新建状态(NEW)
在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态

就绪状态(Runnable)
一个新创建的线程并不自动开始运行,要执行线程,必须调用线程的start()方法。当线程对象调用start()方法即启动了线程,start()方法创建线程运行的系统资源,并调度线程运行run()方法。当start()方法返回后,线程就处于就绪状态。

处于就绪状态的线程并不一定立即运行run()方法,线程还必须同其他线程竞争CPU时间,只有获得CPU时间才可以运行线程。因为在单CPU的计算机系统中,不可能同时运行多个线程,一个时刻仅有一个线程处于运行状态。因此此时可能有多个线程处于就绪状态。对多个处于就绪状态的线程是由Java运行时系统的线程调度程序(thread scheduler)来调度的。

运行状态(Running)
当线程获得CPU时间后,它才进入运行状态,真正开始执行run()方法.

阻塞状态(Blocked)
线程运行过程中,可能由于各种原因进入阻塞状态:

  1. 线程通过调用sleep方法进入睡眠状态;
  2. 线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;
  3. 线程试图得到一个锁,而该锁正被其他线程持有;
  4. 线程在等待某个触发条件;

阻塞状态分三种

  • 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中
  • 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中
  • 其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态

所谓阻塞状态是正在运行的线程没有运行结束,暂时让出CPU,这时其他处于就绪状态的线程就可以获得CPU时间,进入运行状态。

死亡状态(Dead)
进入的条件 :

  • run方法正常退出而自然死亡
  • 一个未捕获的异常终止了run方法而使线程猝死
  • 或者主线程的main()方法完成时,我们就认为它死去

在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常

线程的生命周期为这五种,其实这是操作系统的说法,并不是Java的说法,在Java里面线程有六种状态,对应着枚举类型Thread.Stated的六个枚举常量

线程状态 描述
初始状态(NEW) 新创建了一个线程对象,但还没有调用start()方法
运行状态(RUNNABLE) Java线程中将就绪(ready)和运行中(running)两种状态笼统的成为“运行”。
阻塞状态(BLOCKED) 表示线程阻塞于锁
等待状态(WAITING) 进入该状态的线程需要等待
超时等待状态(TIME_WAITING) 该状态不同于WAITING,它可以在指定的时间内自行返回
终止状态(TERMINATED) 表示该线程已经执行完毕
状态说明
  1. 当线程的run方法结束时,该线程就完成。即线程死亡。但注意,此时线程的状态是死亡了,而且是不可以复活的,但是死亡的线程的对象并没有立即消失(因为Thread是一个类,是一个记录、操作线程的类),特别是在别处被引用下,你可以继续调用这个Thread实例上的大部分方法,而对线程操作的方法基本上都会抛异常,如:start()、wait()、notify()不可以再调用;
  2. 只要线程启动了,也就是调用start()方法,也就永远就不能再次启动;
  3. 线程执行的顺序与线程启动的顺序无关,start()线程启动,线程首先由新建状态变成就绪状态,并不是直接就是运行状态,即不会马上就运行,何时进入CPU运行,得看调度算法;
  4. java 将操作系统当中的就绪 与 运行两个状态合并为运行状态。
  5. 线程进入synchronize修饰的方法或代码块中,线程的状态变为阻塞状态。但如果线程进入的是Lock接口的代码块中,却是等待状态。这是因为Lock对于阻塞的本质实现是使用了LockSupport类中的相关方法。
  6. WAITING 、TIMED_WAITING 两种等待状态都是可以被"中断"打断的,所以那些将线程变为等待状态的方法,如wait()、sleep等都要 捕获 InterruptedException异常。