翻阅了很多帖子,发现对于线程状态的讲述比较粗略,于是自己总结了一篇文章。
参考了
黑马JUC并发编程
Java线程状态RUNNABLE详解
NEW
当线程刚被创建时且还没有调用start()方法时,线程就处于NEW状态,还未与操作系统线程相关联。
这个状态只能进入RUNNABLE状态,且这种状态转换是不可逆的,一旦调用start()就无法再回到NEW状态。
System.out.println(s.getState());
s.start();
System.out.println(s.getState());
NEW
RUNNABLE
我们顺便也复习一下线程创建的几种方式:
- 通过继承Thread,并实现其run方法
可以通过子类普通的继承:
也可以通过匿名类的方式:public class threadTest extends Thread{ @Override public void run() { System.out.println("create thread"); super.run(); } }
这两种方法本质上是一样的。Thread q = new Thread("t1"){ @Override public void run() { super.run(); } }; - 用Runnable接口实现run方法,再将其作为Thread构造函数参数
这种方式将任务的实现与线程分离,且使用Runnable接口不影响类的继承,这里就不再演示了。 - FutureTask配合Thread
FutureTask的构造函数可以接受一个Callable参数。Callable的优势在于:可以返回参数;可以抛出异常
通过对象的get方法,会阻塞直到线程返回结果 - 通过线程池间接创建Thread对象
RUNNABLE
操作系统层面上的线程状态
Java中的这个状态实际上是对操作系统中ready与running状态的包装,甚至也包括了waiting状态。
线程已经与操作系统线程关联,可以被CPU调度执行,既可能处于ready状态,等待被分配时间片,也可能处于running状态,当运行完后,回到ready状态。即线程的上下文切换。
如果线程运行中进行了I/O操作,会导致提前释放时间分片,这个线程就进入等待队列中,也就是处于被阻塞的状态。
这三种状态在Java中都属于RUNNABLE状态。
处于 runnable 状态下的线程正在 Java 虚拟机中执行,但它可能正在等待 来自于操作系统的其它资源,比如处理器
也就是说,Java不关心底层的操作系统是如何运作的,Java中所有的阻塞、等待状态,都是由Java代码本身决定的,而非由底层的操作系统决定。
状态转换
RUNNABLE状态可以转为BLOCKED, WAITING, TIMED_WAITING这几种状态。
情况一:RUNNABLE --> WAITING
- 当线程获取对象锁后,调用wait()方法
注:wait()方法释放锁,并使其进入waitset - 当前线程调用 另一线程t的join()方法时
注:是当前线程在t线程对象的监视器上等待。 - 当前线程调用LockSupport.park()方法
情况二:RUNNABLE --> TIMED_WAITING
- 调用wait(long n)方法, 线程等待n毫秒
- 调用join(long n)方法
- 调用Thread.sleep(long n)方法
情况三:RUNNABLE --> BLOCKED
- 获取对象锁时竞争失败,进入entrylist
情况四:RUNNABLE --> TERMINATED
- 线程所有代码运行完毕
情况五:RUNNABLE --> RUNNABLE
- 当前线程调用yield方法,从运行状态变为可运行状态(相当于running->ready),让出cpu执行时间,但接下来还可能是此线程获得运行时间。
TIMED_WAITING & WAITING
一一与上面对应
情况一:WAITING --> RUNNABLE
- 当前线程调用notify()/notifyAll()之后,等待当前线程代码执行完成后,竞争锁,若成功,则进入RUNNABLE(或者调用interrupt()方法)
- t线程执行完成后,或者调用了之前线程的interrupt()(wait会抛出interrupt异常)
- 调用LockSupport.unpark(目标线程),或调用了线程的interrupt()方法
情况二: TIMED_WAITING --> RUNNABLE
- 除了以上方法外,如果超过了n毫秒,也会导致线程达到相同的效果
情况三:WAITING/TIMED_WAITING -->BLOCKED
- 当从waitset取出来后,进入entrylist处于blocked状态,如果竞争锁失败,则会依然处于此状态
TERMINATED
当线程所有代码执行完毕后,进入此状态,不可逆。
线程的new和terminated符合“先行发生原则”,>表示先行发生
线程启动规则:start()方法
>此线程的每一个动作
线程终止规则:线程所有行为>终止检测,可以通过Thread::join()方法是否结束,或Thread::isAlive()返回值来检验线程终止情况

本文详细介绍了Java线程的各种状态及其转换过程,包括NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED等状态,并探讨了不同状态之间的转换条件。

3972

被折叠的 条评论
为什么被折叠?



