Java并发编程——线程状态与线程方法

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

翻阅了很多帖子,发现对于线程状态的讲述比较粗略,于是自己总结了一篇文章。
参考了
黑马JUC并发编程
Java线程状态RUNNABLE详解

NEW

当线程刚被创建时且还没有调用start()方法时,线程就处于NEW状态,还未与操作系统线程相关联。

这个状态只能进入RUNNABLE状态,且这种状态转换是不可逆的,一旦调用start()就无法再回到NEW状态。

System.out.println(s.getState());
s.start();
System.out.println(s.getState());

NEW
RUNNABLE

我们顺便也复习一下线程创建的几种方式:

  1. 通过继承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();
           }
       };
    
    这两种方法本质上是一样的。
  2. 用Runnable接口实现run方法,再将其作为Thread构造函数参数
    这种方式将任务的实现与线程分离,且使用Runnable接口不影响类的继承,这里就不再演示了。
  3. FutureTask配合Thread
    FutureTask的构造函数可以接受一个Callable参数。Callable的优势在于:可以返回参数;可以抛出异常
    通过对象的get方法,会阻塞直到线程返回结果
  4. 通过线程池间接创建Thread对象

RUNNABLE

操作系统层面上的线程状态

Java中的这个状态实际上是对操作系统中readyrunning状态的包装,甚至也包括了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()返回值来检验线程终止情况

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值