高性能编程——多线程并发编程Java基础篇之线程状态

文章目录

    • 线程状态
    • 线程间状态的转换
    • 线程状态实战

线程状态

线程有6个状态,在Java中通过Thread下的一个枚举类Java.lang.Thread.State可以获取,分别是:

  1. New:尚未启动的线程状态
  2. Runnable:可运行线程的线程状态
  3. Blocked:线程阻塞等待监视器锁定的线程状态,一般都是处于synchronized代码块或者在方法中被阻塞的。
  4. Waiting:等待线程的等待状态,通常就是等待其他线程去唤醒它(详见生产者-消费者模型)下列是不带超时的方式:
    Object.wait()、Thread.join()、LockSupport.park;
  5. Timed Waiting:具有指定等待时间的等待线程的线程状态。下列是带超时的方式:
    Thread.sleep(),Object.wait(int xxx);Thread.join;LockSupport.parkNanos等。
  6. Terminated:终止,线程运行结束的状态

线程间状态的转换

高性能编程——多线程并发编程Java基础篇之线程状态_第1张图片

线程状态实战

package com.study.hc.thread;

public class Demo2 {

    public static Thread thread1;
    public static Demo2 obj;

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

        System.out.println();
        System.out.println("############第二种:新建 -> 运行 -> 等待 -> 运行 -> 终止(sleep方式)###########################");
        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 执行了");
            }
        });
        System.out.println("没调用start方法,thread2当前状态:" + thread2.getState().toString());
        thread2.start();
        System.out.println("调用start方法,thread2当前状态:" + thread2.getState().toString());
        Thread.sleep(200L); // 等待200毫秒,再看状态
        System.out.println("等待200毫秒,再看thread2当前状态:" + thread2.getState().toString());
        Thread.sleep(3000L); // 再等待3秒,让thread2执行完毕,再看状态
        System.out.println("等待3秒,再看thread2当前状态:" + thread2.getState().toString());

        System.out.println();
        System.out.println("############第三种:新建 -> 运行 -> 阻塞 -> 运行 -> 终止###########################");
        Thread thread3 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (Demo2.class) {
                    System.out.println("thread3当前状态:" + Thread.currentThread().getState().toString());
                    System.out.println("thread3 执行了");
                }
            }
        });
        synchronized (Demo2.class) {
            System.out.println("没调用start方法,thread3当前状态:" + thread3.getState().toString());
            thread3.start();
            System.out.println("调用start方法,thread3当前状态:" + thread3.getState().toString());
            Thread.sleep(200L); // 等待200毫秒,再看状态
            System.out.println("等待200毫秒,再看thread3当前状态:" + thread3.getState().toString());
        }
        Thread.sleep(3000L); // 再等待3秒,让thread3执行完毕,再看状态
        System.out.println("等待3秒,让thread3抢到锁,再看thread3当前状态:" + thread3.getState().toString());

    }
}

运行结果:

#######第一种状态切换  - 新建 -> 运行 -> 终止################################
没调用start方法,thread1当前状态:NEW
thread1当前状态:RUNNABLE
thread1 执行了
等待两秒,再看thread1当前状态:TERMINATED

############第二种:新建 -> 运行 -> 等待 -> 运行 -> 终止(sleep方式)###########################
没调用start方法,thread2当前状态:NEW
调用start方法,thread2当前状态:RUNNABLE
等待200毫秒,再看thread2当前状态:TIMED_WAITING
thread2当前状态:RUNNABLE
thread2 执行了
等待3秒,再看thread2当前状态:TERMINATED

############第三种:新建 -> 运行 -> 阻塞 -> 运行 -> 终止###########################
没调用start方法,thread3当前状态:NEW
调用start方法,thread3当前状态:RUNNABLE
等待200毫秒,再看thread3当前状态:BLOCKED
thread3当前状态:RUNNABLE
thread3 执行了
等待3秒,让thread3抢到锁,再看thread3当前状态:TERMINATED

第一段程序解读:
在start之前线程肯定是NEW的,因为此时线程尚未启动。然后start之后,可以发现线程状态是Runnable的,Thread.sleep了两秒(注意,此处是main线程休眠,而不是thread1),这样可以保证线程1执行完成,之后再去获取thread1的状态就是Terminated终止态了,很简单,不难理解。
第二段程序解读:
没start之前和刚启动的时候和第一段没什么差别,但当主线程休眠了200毫秒之后,再去看thread2的状态时却发现它已经是TIMED_WAITING状态,因为此时它正处于sleep方法中,当睡眠结束的时候,继续运行run中的方法,使得打印出线程的状态是RUNNABLE,再等待3秒后输出就是终止态了。
第三段程序解读:
刚开始和前两个没差别,不说了,之后运行的Thread.sleep(200);虽然主线程休眠了,但是并没有释放锁对象,所以这时候缺少临界资源的thread3还是处于阻塞态的,只有当同步代码块运行结束的时候才会释放锁对象,让thread3重新变成了RUNNABLE,这是一种典型的阻塞的实现。

你可能感兴趣的:(高性能编程,多线程)