java基础-线程状态

目录

1、线程的六种状态定义:

2、线程的六种状态之间的切换流程图:


1、线程的六种状态定义

①New(新建状态):尚未启动的线程的线程状态。

        (通俗的说就是我们写了一个线程,还未调用start方法去启动这个线程)

②Runnable(可运行状态):可运行线程的线程状态,等待CUP调度。

        (通俗讲就是,线程调用了start方法之后进入该状态)。Runnable状态分两种:1、CPU正在执行这个线程;2、CPU随时可以调度执行该线程的状态

③Blocked(阻塞状态):线程阻塞等待监视器锁定的线程状态。或处于synchronized同步代码块或方法中阻塞。

④Waiting(等待状态):等待线程的线程状态。

        (等待线程的意思 就是当前线程不执行,一直等待,直到被其他线程状态唤醒之后,会去继续执行的状态。需要依赖另外的线程调度通知的,通知你了才可以继续执行了)

        不带超时的方式:Object.wait、Thread.join、LockSupport.park

⑤Timed Waiting(定时等待状态):具有指定等待时间的等待线程的线程状态。 

        线程调用下面带超时时间的方法进入等待状态,就会有一个等待时间。超过这个等待时间,线程会抛出异常或者继续执行

        带超时的方式:Thread.sleep、object.wait、Thread.join、LockSupport.parkNanos、LockSupport.parkUntil

⑥Terminated(终止状态):终止线程的线程状态。线程正常完成执行或出现异常。

在java的jdk里面定义的状态:java.lang.Thread.Statue

    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;
    }

2、线程的六种状态之间的切换流程图

①第一种状态切换:首先一个线程被创建出来,它是New(新建状态)。调用start方法开始的时候,进入Runnable(可运行状态)。这时候和其他线程抢锁,没抢到,则进入等待Blocked(阻塞状态)。如果你抢到了锁之后,又进入了Runnable可运行状态。

②第二种状态切换:Runnable(可运行状态)的线程,进入Waiting(等待状态),等待其他线程的通知。该线程收到通知,继续执行,才会重新进入Runnable(可运行状态)。收不到通知就会一直处于Waiting(等待状态),等待执行的状态。

②第三种状态切换:Runnable(可运行状态)的线程,进入有超时时间的TimedWaiting(定时等待状态),等待其他线程的通知。TimedWaiting(定时等待状态)会有两种情况可以切换回Runnable(可运行状态)。1、等待超时,等了很久没有收到通知,自己进入Runnable(可运行状态)。2、收到通知,继续执行,进入(Runnable可运行状态)

②第四种状态切换:Runnable(可运行状态)的线程,正常执行结束或者异常的时候,进入Terminated(终止状态)

3、代码演示:

第一种状态切换  - 新建 -> 运行 -> 终止

public class text {

    public static void main(String[] args) throws Exception {

        // 第一种状态切换 - 新建 -> 运行 -> 终止a
        System.out.println("#######第一种状态切换  - 新建 -> 运行 -> 终止################################");
        //创建线程thread1
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                //线程启动之后,打印线程当前状态
                System.out.println("thread1当前状态:" + Thread.currentThread().getState().toString());
                System.out.println("thread1 执行了");
            }
        });
        //创建完线程,再调用start方法启动之前,打印线程当前状态
        System.out.println("没调用start方法,thread1当前状态:" + thread1.getState().toString());
        //线程开始启动
        thread1.start();
        //等待两秒,等待thread1线程执行结束。再看thread1的状态
        Thread.sleep(2000L);
        System.out.println("等待两秒,再看thread1当前状态:" + thread1.getState().toString());
        // thread1.start(); TODO 注意,线程终止之后,再进行start调用,会抛出IllegalThreadStateException异常
    }
}

控制台打印:

第二种:新建 -> 运行 -> 等待 -> 运行 -> 终止(sleep方式)

public class text {

    public static void main(String[] args) throws Exception {

        System.out.println("############第二种:新建 -> 运行 -> 等待 -> 运行 -> 终止(sleep方式)###########################");
        //新建线程thread2
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {// 将线程2移动到定时状态,1500毫秒之后自动唤醒
                    Thread.sleep(1500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("thread2当前状态:" + Thread.currentThread().getState().toString());
                System.out.println("thread2 执行了");
            }
        });
        //线程启动之前,打印当前线程thread2状态
        System.out.println("没调用start方法,thread2当前状态:" + thread2.getState().toString());
        //线程thread2启动
        thread2.start();
        //打印当前线程thread2的状态
        System.out.println("调用start方法,thread2当前状态:" + thread2.getState().toString());
        //主方法main等待200毫秒,让线程thread2执行,再看thread2的线程状态
        Thread.sleep(200L); 
      //线程thread2只要执行,线程thread2调用sleep方法,就会进入定时状态,1500毫秒之后,自动唤醒
        System.out.println("等待200毫秒,再看thread2当前状态:" + thread2.getState().toString());
        // 主线程main方法再等待3秒,让thread2执行完毕,再看状态
        Thread.sleep(3000L);
        System.out.println("等待3秒,再看thread2当前状态:" + thread2.getState().toString());

    }
}

 控制台打印:

  第三种:新建 -> 运行 -> 阻塞 -> 运行 -> 终止

public class Text {

    public static void main(String[] args) throws Exception {

        System.out.println("############第三种:新建 -> 运行 -> 阻塞 -> 运行 -> 终止###########################");
        
        //创建线程3
        Thread thread3 = new Thread(new Runnable() {
            @Override
            public void run() {
                //线程thread3执行,去抢Text这把锁。但是锁是主线程的 抢不到。这段期间它的状态就是阻塞状态
                // 主线程执行完毕,释放Text锁,thread3这个线程才能拿到锁,往下执行
                synchronized (Text.class) {
                    System.out.println("thread3当前状态:" + Thread.currentThread().getState().toString());
                    System.out.println("thread3 执行了");
                }
            }
        });

        //当thread2、thread3两个线程本创建之后。当前主线程拿到Text锁
        synchronized (Text.class) {
            //未开启thread3,
            System.out.println("没调用start方法,thread3当前状态:" + thread3.getState().toString());
            //开启线程thread3
            thread3.start();
            //线程thread3刚启动,还未抢到锁。打印状态
            System.out.println("调用start方法,thread3当前状态:" + thread3.getState().toString());
            // 主线程等待200毫秒,再看thread3的线程状态
            Thread.sleep(200L);
            System.out.println("等待200毫秒,再看thread3当前状态:" + thread3.getState().toString());
        }
        //这里主线程就释放Text锁啦

        // 主线程再等待3秒,让thread3执行完毕,再看状态
        Thread.sleep(3000L);
        //thread3 拿到锁,执行完毕了  打印状态
        System.out.println("等待3秒,让thread3抢到锁,再看thread3当前状态:" + thread3.getState().toString());

    }
}

控制台打印:

 

总结:

通过下面的流程图,通过调用api来切换不同的流程状态 


版权声明:本文为LemonSnm原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。