前言
本文介绍下线程的3种实现方式并深入源码简单的阐述下原理
三种实现方式
Thread
深入源码简单刨析
Thread
Thread类实现了Runnable接口
枚举类 State
JVM中的线程必须只能是以上6种状态的一种。这些状态是JVM状态并不能和操作系统线程状态互相映射
- NEW
线程刚创建,还未执行(start方法)
- RUNNABLE
已就绪可运行的状态。 处于此状态的线程是正在JVM中运行的, 但可能在等待操作系统级别的资源,例如CPU时间片
- BLOCKED
阻塞等待监视器锁 处于此状态的线程正在阻塞等待监视器锁, 以进入一个同步块/方法, 或者在执行完wait()方法后重入同步块/方法
- WAITING
等待 执行完Object.wait无超时参数操作, 或者 Thread.join无超时参数操作(进入等待指定的线程执行结束), 或者 LockSupport.park操作后,线程进入等待状态。 一般在等待状态的线程在等待其它线程执行特殊操作, 例如:等待另其它线程操作Object.notify()唤醒或者Object.notifyAll()唤醒所有。
- TIMED_WAITING
限时等待 Thread.sleep、Object.wait带超时时间、 Thread.join带超时时间、 LockSupport.parkNanos、 LockSupport.parkUntil这些操作会时线程进入限时等待
- TERMINATED
终止,线程执行完毕
线程状态流转
JVM 线程状态流转图
注意:不要混淆操作系统线程状态和java线程状态。JVM中的线程必须只能是以上6种状态的一种!RUNNABLE = 正在JVM中运行的(Running)+ 可能在等待操作系统级别的资源(Ready)例如CPU时间片
- 线程创建之后,不会立即进入就绪状态,因为线程的运行需要一些条件(比如内存资源),
- 只有线程运行需要的所有条件满足了,才进入就绪状态。
- 当线程进入就绪状态后,不代表立刻就能获取CPU执行时间,也许此时CPU正在执行其他的事情,因此它要等待。
- 当得到CPU执行时间之后,线程便真正进入运行状态。
- 线程在运行状态过程中,可能有多个原因导致当前线程不继续运行下去,比如用户主动让线程睡眠(睡眠一定的时间之后再重新执行)、用户主动让线程等待,或者被同步块给阻塞,此时就对应着多个状态:time waiting(睡眠或等待一定的事件)、waiting(等待被唤醒)、blocked(阻塞)。
- 当由于突然中断或者子任务执行完毕,线程就会被消亡。