Java中的线程状态

参考:https://my.oschina.net/goldenshaw?tab=newest&catalogId=3277710

1 线程状态

Java中的线程一共有6种状态。

在某个时刻,Java中的线程只能处于这6种状态中的一种。

1.1 线程状态的定义

Java中的线程状态被明确地定义在Thread.State中:

public enum State {

        /**
         * 新建
         */
        NEW,

        /**
         * 可运行
         */
        RUNNABLE,

        /**
         * 阻塞
         */
        BLOCKED,

        /**
         * 等待
         */
        WAITING,

        /**
         * 超时等待
         */
        TIMED_WAITING,

        /**
         * 终止
         */
        TERMINATED;
    }

下面是各状态的说明:

线程状态说明
NEW一个线程被创建出来,但是还没有启动(调用Thread.start()方法)的时候。
RUNNABLE一个正在 Java 虚拟机中执行的线程处于这一状态。
BLOCKED一个正在阻塞等待一个监视器锁的线程处于这一状态。
WAITING一个正在无限期等待另一个线程执行一个特定的动作(通知或中断)的线程处于这一状态。
TIMED_WAITING一个正在有限的时间内等待另一个线程执行一个特定的动作(通知或中断)的线程处于这一状态。
TERMINATED一个已经退出的线程处于这一状态。

1.2 线程状态转换图

在这里插入图片描述

2 线程状态详解

2.1 NEW(新建状态)

  • 线程被new创建出来后,但是还没有执行线程的start()方法,这时候线程是没有启动的,此状态就是NEW状态。
  • 想要启动一个线程,必须执行start()方法。如果执行run()方法,只会在调用方所在的线程中执行,并没有启动一个新的线程。

2.2 RUNNABLE(可运行状态)

  • RUNNABLE状态是JVM虚拟机对线程状态的一种描述,不是操作系统对线程状态的描述。
  • JVM虚拟机中的线程状态与操作系统中的线程状态不是一回事。
  • RUNNABLE状态实际上对应了操作系统中的READY(就绪)状态、RUNNING(运行)状态、部分WAITING状态。
  • 处于RUNNABLE状态的线程表示正在Java虚拟机中运行,但是它可能正在等待来自于操作系统的其它资源,比如处理器。

注意:进行阻塞式 I/O 操作时,Java 的线程状态还是RUNNABLE,并不是BLOCKEDWAITING!!!

看下面的例子:

// 创建一个线程,等待I/O输入
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        try (Scanner in = new Scanner(System.in);) {
            String input = in.nextLine();
            System.out.println(input);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});

// 启动这个线程
thread.start();

// 确保子线程被启动
Thread.sleep(1000);

System.out.println(thread.getState());  // RUNNABLE

2.3 BLOCKED(阻塞状态)

  • BLOCKED状态不是通常意义上的 “ 阻塞 ”,线程的BLOCKED状态是针对于synchronized代码块或方法而言的。

线程在请求获取monitor锁时,如果这个锁已经被其他线程获取了,那么这个线程将要 “ 阻塞 ” 等待着获取这个monitor锁,以便进入synchronized代码块/方法。

或者在这个线程已经进入了同步块/方法之后,然后调用了Object.wait()方法,这个线程将会释放该锁,并进入锁的等待队列(wait set)中。之后被其他线程唤醒,这个时候这个锁可能已经被其他线程获取了,所以这个线程需要 “ 阻塞 ” 等待着重新获取monitor锁,以便 再次 进入这个synchronized代码块/方法,然后从上次wait()的地方恢复执行。

  • 线程等待着获取锁被阻塞在同步块之外的这个状态就是BLOCKED状态。

BLOCKED 状态可以视作是一种特殊的 WAITING,特指等待

注意:这一状态的进入及解除都不受我们控制,当锁可用时,线程就会从阻塞状态中恢复。

2.4 WAITING(等待状态)

一个线程正在无限期等待另一个线程执行一个特别的动作,这个状态就是WAITING

一个线程进入WAITING状态是因为调用了以下方法:

  1. 不带超时时间的Object.wait()方法

  2. 不带超时时间的Thread.join()方法

  3. LockSupport.park()

其他线程执行的特别动作,可能是:

  1. 调用Object.notify()或者Object.notifyAll()

  2. 线程结束(针对的是调用了这个线程的Thread.join()方法)

BLOCKED不同在于,进入WAITING状态的线程,会被放入wait set中。这时,线程不再活动,不再参与调度,因此不会浪费CPU资源,也不会竞争锁,直到另一个线程执行一个特别的动作,这个线程才会被唤醒。

处于WAITING状态的线程被唤醒之后,如果能够获得锁,线程就会从WAITING状态变成RUNNABLE状态;否则,从wait set出来,又进入entry set,需要去竞争锁,线程就从WAITING状态变成BLOCKED状态。

2.5 TIMED_WAITING(超时等待状态)

TIMED_WAITING是带超时时间的WAITING状态。

一个正在限时等待另一个线程执行一个动作的线程处于这一状态。

一个线程进入TIMED_WAITING状态是因为调用以下方法:

  1. 带超时时间的Thread.sleep
  2. 带超时时间的Object.wait
  3. 带超时时间的Thread.join
  4. LockSupport.parkNanos
  5. LockSupport.parkUntil

超时时间到,即使没有被唤醒,线程也会自己醒来。

2.6 TERMINATED(终止状态)

一个已经退出的线程处于这一状态。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值