线程的生命周期,状态是如何转移的

Thread类里有个枚举类:

public enum State {
			//新建状态
	        NEW, 
	        //Runnable状态
	        RUNNABLE,
	        //Block阻塞状态
	        BLOCKED,
	        //Waiting等待状态
	        WAITING,
	        //TimedWaiting等待状态
	        TIMED_WAITING,	
	        //Terminaled结束状态
	        TERMINATED;
	    }

从Thread.State 从这个枚举类里看,java的线程有6个状态:

NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED

下图详细描述了线程生命周期各个状态以及状态之间之间的转换时机

1.新建

New一个线程,还没有调用start(); 时处于新建状态。

2.Runnable状态

线程对象调用start();方法时,它会被线程调度器来执行(也就是交给操作系统执行),操作系统执行的时候,这整个状态叫Runnable状态,Runnable内部又有两个状态:

  • a) Ready就绪状态

​ 扔到CPU的等待队列里去等待CPU运行

  • b) Running状态

​ 等真正扔到CPU上去运行的时候叫Running.(调用yield方法,从Running-->Ready,线程调度器选中执行的时候 Ready--->Running)

3.Terminaled结束状态

线程顺利执行完了进入Terminaled结束状态(不可以再回到new状态调用start,这就算结束了)

Runnable还有一些其他状态:

4.TimedWaiting等待

按照时间等待,等待时间结束了自己就到了Running状态。

  1. Thread.sleep(time);
  2. o.wait(time);
  3. t.join(time);
  4. LockSupport.parkNanos()

都是关于时间等待的方法

5.Waiting等待

在运行过程中,如果调用了:

  1. o.wait();
  2. t.join();
  3. LockSupport.park();

进入waiting状态;

调用

  1. ​ o.notify();
  2. ​ o.notifyAll();
  3. ​ LockSupport.unpark();

又回到Running状态

6.Block阻塞

同步代码块没有获得锁就会阻塞状态,获得锁就是就绪状态

追问1:这些状态,哪些是JVM管理的,哪些是操作系统管理的?

这些状态全是由JVM管理的,因为JVM管理的时候也要通过操作系统,所以,哪个是JVM哪个是操作系统,他俩分不开。JVM是跑在操作系统上的一个普通程序。

追问2:线程什么时候会被挂起?挂起是否也是一个状态?

Running的时候,在一个CPU上会跑很多个线程,CPU会隔一段时间执行这个线程一下,在隔一段时间执行那个线程一下,这是CPU内部的一个调度,把这个状态线程扔出去,从Running扔出去,就叫线程被挂起,CPU控制它。

欢迎关注公众号交流学习,会分享更多项目实践以及学习资料: