您的位置 首页 java

「java实战系列」多线程开发|基础篇|第二讲|线程的状态

第一讲主要介绍了 java 实现 多线程 的方式,要想玩转多线程,首先要知道 线程 的状态有哪些。本篇文章就和大家一起看一看,线程的状态有哪些,以及各状态间如何转换。

一、线程的状态

在网上可以搜到各种各样的关于线程状态的文章,我还是基于 Thread 类的源码,来给大家简单讲一讲,如下图所示,Thread类中有内部枚举类中有六种状态:

 public  enum  State {
    NEW,
    RUNNABLE,
    BLOCKED,
    WAITING,
    TIMED_WAITING,
    TERMINATED;
}  
「java实战系列」多线程开发|基础篇|第二讲|线程的状态

首先,我们对这六种状态一 一解释。

1、NEW(初始化)状态

实例化一个Thread类对象出来(未执行start()方法前),Thread的状态为NEW。

2、RUNNABLE(可运行)状态

调用线程的start()方法,此时线程进入RUNNABLE状态,该状态的线程位于可运行 线程池 中,等待被操作系统调度,获取 CPU 的使用权。当获得CPU的时间片时,线程进入运行状态,执行程序代码。

3、BLOCKED(阻塞)状态

当线程等待获取monitor锁( synchronized )时,线程就会进入BLOCKED状态。

等待获取monitor锁,线程的状态是BLOCKED。

等待获取Lock锁(LockSupport.park()),线程的状态是WAITING

4、TIMED_WAITING(超时等待)状态

5、WAITING(等待)状态

6、TERMINATED(终止)状态

当线程执行完毕、Thread.stop()、内存溢出时,线程就会进入TERMINATED状态。线程一旦死亡,就无法复活。在一个死亡的线程上调用start()方法,会抛出java.lang.IllegalThreadState Exception 异常

二、线程各类状态的转换

基于上述描述,下图的状态变更图片更直观的展示了各个状态的变化关系。

「java实战系列」多线程开发|基础篇|第二讲|线程的状态

三、线程状态相关API

1、线程睡眠sleep

我们常用sleep来模拟网络延时、倒计时等场景,那sleep如何正确使用呢?我们来看一下源码Thread类提供了两个sleep()方法。代码如下图:

 public  static  native  void  sleep(long millis) throws InterruptedException;  
 public static void sleep(long millis, int nanos)
throws InterruptedException {
    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

    if (nanos < 0 || nanos > 999999) {
        throw new IllegalArgumentException(
                            "nanosecond timeout value out of range");
    }

    if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
        millis++;
    }

    sleep(millis);
}  

通过上述代码可以看出

1) sleep存在异常 Interrupted Exception。

2)threa d类中的sleep方法没有实现ns级别的睡眠。注意看代码第12行,

①当nanos大于等于500微秒时,millis就加1.当nanos小于500微秒时,不改变millis的值.

②当millis的值为0时,只要nanos不为0,就将millis设置为1.

因此,睡眠的最小单位仍为millis.最小的睡眠时间为1millis

2、线程礼让 yield

礼让线程,让当前正在执行的线程暂停,但是不阻塞。

让线程从运行状态转为就绪状态

让CPU重新调度,但是不一定成功。

 public static native void yield();  

3、线程合并join

join()的作用是插队,待此线程执行完毕后再执行其他线程,这时候造成其他线程的阻塞。

总结:

其它API就不一一讲解,大家可以看到,线程的状态偶那么多,一个线程的创建到使用完成,是多么麻烦,所以在之前一讲中提到的四种创建线程的方法,前三种在实际工作中尽量不要使用。在下一章中,会给大家介绍线程池的使用方法,敬请期待。

文章来源:智云一二三科技

文章标题:「java实战系列」多线程开发|基础篇|第二讲|线程的状态

文章地址:https://www.zhihuclub.com/190880.shtml

关于作者: 智云科技

热门文章

网站地图