第一部分:并发理论基础09->Java线程的生命周期

1.java的线程与操作系统线程一一对应

2.通用线程生命周期

初试状态,可运行状态,运行状态,休眠状态,终止状态

image

初试状态,线程已经被创建,还不允许被cpu执行,编程语言特有的,而操作系统还没有被创建

可运行状态,线程可以被cpu执行,这种状态下,真正操作系统的线程已经被成功创建了,可以分配cpu执行

运行状态,当空闲cpu时,操作系统会将其分配给一个处于可运行状态的线程,被分配到cpu线程的状态就转成了运行状态

休眠状态,运行态的线程执行了阻塞的API或者等待某个条件(wait,await),那么线程的状态就会变为休眠状态,释放cpu使用权,休眠状态的线程永远没有机会获取cpu使用权,等待事件出现了,线程从休眠状态转为可运行状态

终止状态,线程执行完或出现异常进入终止状态,终止状态的线程不会切换到其他任何状态 ,生命周期结束

3.java的线程生命周期

NEW(初始化状态)
RUNNABLE(可运行/运行状态)
BLOCKED(阻塞状态)
WAITING(无限时等待)【 wait,await就线程切换为这个状态 】
TIMED_WAITING(有时间等待)【 sleep方法就切换到了这个状态 】
TERMINATED(终止状态)

比通用的线程状态多了BLOCKED,WAITING,TIMED_WAITING这3种,其实对应到操作系统层面,是一种状态就是休眠状态,就没有cpu的使用权

image

4.BLOCKED状态出现的时机

RUNNABLE 到BLOCKED 状态的转换

线程等待synchronized的隐式锁,synchronized修饰方法代码块同一时间只允许一个线程运行,其他线程等待

等待的线程就会从RUNNABLE 切换到BLOCKED状态,当等待的线程获得synchronized隐式锁时候,从BLOCKED切回RUNNABLE

那么线程调用阻塞API,是否会切换到BLOCKED状态呢?
操作系统线程会切换到休眠状态,但是java的jvm层面,线程状态还是RUNNABLE状态。jvm层面不关系操作系统调度相关的状态。jvm来看,等待cpu与等待io没有区别,所以是RUNNABLE状态

5.WAITING状态出现的时机

三种情景
1.获取synchronized隐式锁的线程,调用无参的object.wait()方法
2.调用无参的thread.join(),线程同步方法,等待线程执行完毕,等待中的这个线程会从RUNNABLE切换到WAITING状态,线程执行完毕后,从WAITING切回RUNNABLE
3.LockSupport.park()方法,并发包中的锁,基于它实现,await方法

6.TIMED_WAITING出现的时机

5种常见
1.调用带超时参数的Thread.sleep()方法
2.获取synchronized隐式锁,调用带超时参数的object.wait(long timeout)
3.调用带超时参数的Thread.join(long millis)
4.调用带超时参数的LockSupport.partNanos
5.调用带超时参数的LockSupport.parkUnit

7.Runnable状态出现的时机

java刚创建出来的Thread对象就是NEW状态

Thread thread = new Thread();

此时是new状态
调用
thread.start()线程状态切换到RUNNABLE状态

7.TERMINATED状态出现的时机

执行完run方法后,自动转换到TERMINATED状态

java的Thread类里有一个interrupt()方法

interrupt通知线程,线程可以执行后续操作,同时也可以无视。
线程在WAITING,TIMED_WAITING状态,被执行interrupt,会状态切回RUNNABLE状态,同时触发InterruptedException异常

线程在RUNNABLE状态,并没有阻塞在某个io上,就依赖线程自己主动检测中断状态了。

posted @ 2021-06-30 17:40  SpecialSpeculator  阅读(40)  评论(0编辑  收藏  举报