3.线程一共有哪些状态呢?

在上一章节中我们了解到线程怎么创建和执行。在实际开发过程中多线程是很容易出现问题的,一不小心可能会导致死锁从而引起整个系统崩溃。只有对线程的整个运行过程比较了解才能及时地去找到问题在哪。不知道大家有没有想过下面几个问题,

  1. 一共有哪些线程状态呢?
  2. 为什么要了解这些线程状态呢?
  3. 这些状态怎么查看呢?

我相信带着问题去学习是一种更高效的学习方式。接下来我会给小伙伴们一一找到答案。

image.png

上图是综合了线程一般状态和JVM中线程状态,其中红框等待timed_waiting、 等待waiting、阻塞blocked都是JVM的线程状态,JVM线程状态在JDK中有一个枚举类java.lang.Thread.State表示:

    public enum State {
        /**
         * 线程还没有启动时的状态
         */
        NEW,

        /**
         * 可运行状态。
         */
        RUNNABLE,

        /**
         * 进入synchronized同步代码块
         */
        BLOCKED,

        /**
         * 执行以下方法进入WAITING状态
         * Object.wait
         * Thread.join
         * LockSupport.park
         */
        WAITING,

        /**
         * 执行以下带有时间的方法进入TIMED_WAITING状态
         * Thread.sleep(long)
         * Object.wait(long)
         * Thread.join(long)
         * LockSupport.parkNanos
         * LockSupport.parkUntil
         */
        TIMED_WAITING,

        /**
         * 终止或者消亡状态
         */
        TERMINATED;
    }

下面我们通过代码和jstack命令演示下不同方法调用对一个的不同状态

  1. sleep(long)会使线程进入timed_waiting状态
    /**
     * 调用sleep(long)线程处于timed_waiting状态
     *
     * @author jinglei
     * @date 2020/8/21 13:09
     */
    public class TimedWaitingBySleep {

        public static void main(String[] args) {
            //1.sleep
            Thread sleepThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("调用sleep()之后线程处于timed_waiting状态");
                    try {
                        Thread.currentThread().sleep(50000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            sleepThread.setName("mythread-sleep");

            //启动线程
            sleepThread.start();
        }
    }

运行程序,然后通过jps命令找到对应的进程id,再用jstack processId > D:/test/sleepTimedWaiting.log把线程堆栈输出到文件
3.线程一共有哪些状态呢?_第1张图片

文件内容如下图
3.线程一共有哪些状态呢?_第2张图片
可以看出mythread-sleep这个线程处于java.lang.Thread.State: TIMED_WAITING (sleeping)这个状态。

通过jstack查看线程堆栈的这种方法要学会使用,以后排查问题可能会遇到,比如网上经典的面试题“生产环境出现了cpu100%,你怎么排查”这时候jstack就派上大用场了。

  1. wait(long)会使线程进入timed_waiting状态

/**
 * 调用wait(long)线程处于timed_waiting状态
 *
 * @author jinglei
 * @date 2020/8/21 13:09
 */
public class TimedWaitingByWait {

    private static Object lock = new Object();

    public static void main(String[] args) {
        //2.wait(long)
        Thread waitLongThread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("wait(long)之后线程处于timed_waiting状态");
                synchronized (lock){
                    try {
                        lock.wait(50000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println();
                }
            }
        });
        waitLongThread.setName("mythread-waitLong");

        //启动线程
        waitLongThread.start();
    }
}

通过上面的方法查看到的线程状态如下图

3.线程一共有哪些状态呢?_第3张图片

你可能感兴趣的:(多线程)