从操作系统以及Java层面对线程状态的分析

线程的几种状态

线程的状态到底有几种,从不同的角度分析会得到不同的结果。有的说5种,也有的说6种。今天我们以操作系统和java的层面来了解下线程的几种状态。

操作系统

操作系统多线程有五种状态

在这里插入图片描述

  • 【初始状态】 仅仅在语言层面创建了线程
  • 【可运行状态】 已经准备就绪,准备CPU的调度。
  • 【运行状态】获取了CPU时间片,正在运行。时间片用完后,会导致线程上下文切换。线程会重新去竞争时间片,变为【可运行状态】。
  • 【阻塞状态】 如果线程调用了阻塞API,例如,BIO读写文件。此时线程不会用到CPU资源,进入阻塞状态。当阻塞操作结束后,操作系统唤醒阻塞线程转换为【可运行状态】。只要操作系统不唤醒,CPU就不会考虑调度它。
  • 【停止状态】 线程执行完毕,整个生命周期结束。

Java层面

首先我们先看看Thread中的枚举类型State,Java多线程有六种状态

public enum State {
    /**
     * Thread state for a thread which has not yet started.
     * 尚未启动的线程的线程状态。
     */
    NEW,

    /**
     * Thread state for a runnable thread.  A thread in the runnable
     * state is executing in the Java virtual machine but it may
     * be waiting for other resources from the operating system
     * such as processor.
     * 
     * 可运行线程的线程状态。处于可运行状态的线程正在Java虚拟机中执行,但它可能正在等待来自操作系统(例如处理器)的其他资源。
     */
    RUNNABLE,

    /**
     * Thread state for a thread blocked waiting for a monitor lock.
     * A thread in the blocked state is waiting for a monitor lock
     * to enter a synchronized block/method or
     * reenter a synchronized block/method after calling
     * {@link Object#wait() Object.wait}.
     * 
     * 线程的线程状态被阻塞,等待监视器锁定。
     * 处于阻塞状态的线程在调用{@link Object#wait()Object.wait}之后,
     * 正在等待监视器锁定输入同步的块/方法或重新输入同步的块/方法。
     */
    BLOCKED,

    /**
     * Thread state for a waiting thread.
     * A thread is in the waiting state due to calling one of the
     * following methods:
     * <ul>
     *   <li>{@link Object#wait() Object.wait} with no timeout</li>
     *   <li>{@link #join() Thread.join} with no timeout</li>
     *   <li>{@link LockSupport#park() LockSupport.park}</li>
     * </ul>
     *
     * <p>A thread in the waiting state is waiting for another thread to
     * perform a particular action.
     *
     * For example, a thread that has called <tt>Object.wait()</tt>
     * on an object is waiting for another thread to call
     * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
     * that object. A thread that has called <tt>Thread.join()</tt>
     * is waiting for a specified thread to terminate.
     * 
     * 等待线程的线程状态。线程由于调用以下方法之一而处于等待状态:
     * <ul>
     * <li>{@link Object#wait() Object.wait} 没有超时</li>
     * <li>{@link #join() Thread.join} 没有超时</li>
     * <li>{@link LockSupport#park() LockSupport.park}</li>
     * </ul>
     * <p>处于等待状态的线程正在等待另一个线程执行特定操作。例如,
     * 在某个对象上调用了<tt> Object.wait()</ tt>的线程
     * 正在等待另一个线程调用<tt> Object.notify()</ tt> 或<tt> Object.notifyAll( )</ tt>。
     * 名为<tt> Thread.join()</ tt>的线程正在等待指定的线程终止。
     */
    WAITING,

    /**
     * Thread state for a waiting thread with a specified waiting time.
     * A thread is in the timed waiting state due to calling one of
     * the following methods with a specified positive waiting time:
     * 
     * 具有指定等待时间的等待线程的线程状态。由于以指定的正等待时间调用以下方法之一,因此线程处于定时等待状态:
     * <ul>
     *   <li>{@link #sleep Thread.sleep}</li>
     *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
     *   <li>{@link #join(long) Thread.join} with timeout</li>
     *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
     *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
     * </ul>
     */
    TIMED_WAITING,

    /**
     * Thread state for a terminated thread.
     * The thread has completed execution.
     * 终止线程的线程状态。线程已完成执行。
     */
    TERMINATED;
}

可以看出Java中的线程是有六种状态的,在Thread中State的状态上都有标明各种状态都是如何转换的。

在这里插入图片描述

通过State中 RUNNABLE 的介绍,可知在Java中线程的就绪和运行都是 RUNNABLE 类型,为了方便我们作图,所以在图中加入了 已就绪

下面我们来展示这五种状态

//锁对象
Object lock = new Object();
Thread t1 = new Thread("t1") {
    @Override
    public void run() {
    }
};
Thread t2 = new Thread("t2") {
    @Override
    public void run() {
        while (true) {
        }
    }
};
Thread t3 = new Thread("t3") {
    @Override
    public void run() {
        try {
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};

Thread t4 = new Thread("t4") {
    @Override
    public void run() {
        synchronized (lock) {
            try {
             TimeUnit.SECONDS.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
};

Thread t5 = new Thread("t5t5") {
    @Override
    public void run() {
    }
};

Thread t6 = new Thread("t6") {
    @Override
    public void run() {
        synchronized (lock) {
            try {
             	TimeUnit.SECONDS.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
};

t2.start();
t3.start();
t4.start();
t5.start();
t6.start();

log.debug("t1:{}", t1.getState());
log.debug("t2:{}", t2.getState());
log.debug("t3:{}", t3.getState());
log.debug("t4:{}", t4.getState());
log.debug("t5:{}", t5.getState());
log.debug("t6:{}", t6.getState());

执行结果

16:12:32.418 [main] DEBUG ThreadTest - t1:NEW
16:12:32.426 [main] DEBUG ThreadTest - t2:RUNNABLE
16:12:32.426 [main] DEBUG ThreadTest - t3:WAITING
16:12:32.426 [main] DEBUG ThreadTest - t4:TIMED_WAITING
16:12:32.426 [main] DEBUG ThreadTest - t5:TERMINATED
16:12:32.426 [main] DEBUG ThreadTest - t6:BLOCKED

介绍

  • 【t1】 创建了,没有start,所以状态为NEW
  • 【t2】 t2中是while死循,一直在执行。所以状态为RUNNABLE
  • 【t3】t3中把t2 join进来了,需要等待t2执行完毕才能执行t3。所以状态为WAITING
  • 【t4】t4中线程获取到锁后就sleep了。所以状态为TIMED_WAITING
  • 【t5】t5代码直接很顺畅的执行完毕。所以状态为TERMINATED
  • 【t6】t6和t4持有的是同一锁(锁的是同一个对象lock),在t4释放锁之前t6会一直阻塞。所以状态为BLOCKED
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值