线程的状态Thread.State

博客推荐

前言

网上很多文章讲线程状态的,但是多数为了好理解,进行了一定的改变,使得准确性不够。
本文根据Thread类中的枚举类State为切入点,对这一知识点进行总结,通过理解这个知识点,为以后的系统故障排查,JVM调优打下坚实的基础。
在阅读以下内容时,需要了解两个jdk自带的小工具,jps,jstack(后续补充一篇jdk工具的备忘)。

5种状态

  • State.NEW : 初始状态,线程已构建,但start()还未调用
  • State.RUNABLE : 运行状态,对应于常说的就绪状态和运行状态的合集
  • State.BLOCKED : 阻塞状态,阻塞于锁(注意,阻塞于Lock锁不属于这个状态,仅仅限于synchronized锁)
  • State.WAITING : 等待状态,等待一些特定动作来打破这一状态(比如通知、中断)
  • State.TIMED_WAITING : 超时等待状态,两种情况打破该状态,1.超过指定时间;2.一些特定动作
  • State.TERMINATED : 终止状态,表示线程死亡

注意:

  1. java将操作系统中的运行和就绪两个状态合并称为运行状态
  2. 阻塞状态时线程阻塞在进入synchronized关键字修饰的方法或代码块时的状态
  3. java.concurrent包中的Lock接口的线程状态是等待状态(超时等待状态),因为该接口对于阻塞的实现均使用了LockSupport类中的相关方法

相关方法

  • thread.start() : 由初始状态转为运行状态(就绪状态)
  • thread.yield():仍处于RUNNABLE状态,从操作系统的线程角度,仅仅交出cpu使用权,由运行状态转为就绪状态,优先级比较高的情况下,会立马再次获取cpu。
  • Object.wait()/Object.join()/LockSupport.park():由运行状态转为等待状态
  • thread.sleep(long)/Object.wait(long)/Object.join(long)/LockSupport.parkNanos()/LockSupport.parkUntil():由运行状态转为超时等待状态
  • Object.notify()/Object.notifyAll()/LockSupport.unpark(thread):由等待状态(超时等待状态)转为运行状态

状态装换示意图

摘自《Java并发编程的艺术》

[thread状态转换]

代码演示

  • State.NEW :
  • State.RUNABLE :
  • State.TERMINATED :

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(){
            @Override
            public void run() {
                for(int i = 0 ; i < 100000 ; i++){}
            }
        };
        t.setName("test");
        System.out.println("第一处打印,线程状态:" + t.getState());
        t.start();
        System.out.println("第二处打印,线程状态:" + t.getState());
        Thread.currentThread().sleep(2000);
        System.out.println("第三处打印,线程状态:" + t.getState());
    
    }
    //控制台
    第一处打印,线程状态:NEW
    第二处打印,线程状态:RUNNABLE
    第三处打印,线程状态:TERMINATED
    
  • State.BLOCKED :

    Thread t1 = new Thread(){
            @Override
            public void run() {
                synchronized(ThreadStateTest.class){
                    while(true){}
                }
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run() {
                synchronized(ThreadStateTest.class){
    
                }
            }
        };
        t1.setName("t1");
        t2.setName("t2");
        t1.start();
        t2.start();
        Thread.currentThread().sleep(1000);
        System.out.println("第四处打印,线程状态:" + t1.getState());//第四处打印,线程状态:RUNNABLE
        System.out.println("第五处打印,线程状态:" + t2.getState());//第五处打印,线程状态:BLOCKED
    }
    
  • State.WAITING :

    //===============WAITING===================//
        Thread t3 = new Thread(){
            @Override
            public void run() {
                synchronized(this){
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
    
};
t3.setName("t3");
t3.start();
Thread.currentThread().sleep(1000);
System.out.println("第六处打印,线程状态:" + t3.getState());//第六处打印,线程状态:WAITING

//===============WAITING===================//
/*Thread t3_1 = new Thread(){
    @Override
    public void run() {
        while(true){}
    }


};
t3_1.setName("t3_1");
t3_1.start();
Thread.currentThread().sleep(1000);
Thread.currentThread().setName("main");
t3_1.join();*/
//使用jps,jstack工具查看,结果如下:

"t3_1" prio=6 tid=0x49e1f000 nid=0x242c runnable [0x4a25f000]
java.lang.Thread.State: RUNNABLE
at com.kevinlsui.multithread.Test2$1.run(Test2.java:25)

"main" prio=6 tid=0x002acc00 nid=0x2408 in Object.wait() [0x01abf000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x03c9b190> (a com.kevinlsui.multithread.Test2$1)
at java.lang.Thread.join(Thread.java:1281)
- locked <0x03c9b190> (a com.kevinlsui.multithread.Test2$1)
at java.lang.Thread.join(Thread.java:1355)
at com.kevinlsui.multithread.Test2.main(Test2.java:35)

//LockSupport相关,暂无研究
  • State.TIMED_WAITING

    //===============TIMED_WAITING===================//
        Thread t4 = new Thread(){
            @Override
            public void run() {
                synchronized(this){
                    try {
                        this.wait(10000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    /*try {
                        sleep(10000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }*/
                }
            }
    
};
t4.setName("t4");
t4.start();
Thread.currentThread().sleep(1000);
System.out.println("第七处打印,线程状态:" + t4.getState());//第七处打印,线程状态:TIMED_WAITING

//join(1000)测试需要使用jps,jstack查看,同上t3_1案例
//LockSupport相关,暂无研究

State源码

//jdk7
 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.
     */
    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}.
     */
    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.
     */
    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;
}
文章目录
  1. 1. 前言
  2. 2. 5种状态
  3. 3. 相关方法
  4. 4. 状态装换示意图
  5. 5. 代码演示
  6. 6. State源码
|