【Java 并发编程】Java 线程的生命周期

1. 概述

本文来一起学习 Java 线程的生命周期,线程从创建到销毁是有生命周期的,在线程的生命周期中,线程会经历多种状态(state):new - 初始、runnable - 运行、blocked - 阻塞、waiting - 等待、timed_waiting - 超时等待、terminated - 终止

2. 线程状态之间的流转

java.lang.Thread 类中有一个静态枚举类:State,用来表示线程各种可能的状态:

public enum State {
    
    

    NEW,

    RUNNABLE,

    BLOCKED,

    WAITING,

    TIMED_WAITING,

    TERMINATED;
}

2.1 NEW - 初始

NEW 状态表示新建了一个线程,但尚未启动。

2.2 RUNNABLE - 运行

RUNNABLE 状态表示线程可运行,Java 线程中将就绪(ready)和运行中(running)两种状态笼统的称为 “运行”。

线程对象创建后,其他线程(比如 main 线程)调用了该对象的 start() 方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取 CPU 的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得 CPU 时间片后变为运行中状态(running)。

2.3 BLOCKED - 阻塞

WAITING 状态表示线程阻塞于监视器锁(monitor lock)。

获取到监视器锁后可以进入同步代码块或者同步方法(synchronized block/method),当然可能是首次等待,也可能是调用 Object.wait() 等待之后再被唤醒( Object.notify() 或者 Object.notifyAll() )后,因为唤醒后一般不能直接进入 Runnable 状态,需要重新争抢监视器锁,这时仍然是 BLOCKED 状态。

2.4 WAITING - 等待

WAITING 状态表示当前线程正在等待其他线程的一些动作(无超时时间的等待),包括以下场景(通知或中断):

  • Object.wait() - 调用之后等待其他线程调用 Object.notify() 或者 Object.notifyAll()

  • Thread.join() - 调用之后等待指定的线程终止(进入 TERMINATED 状态)

  • LockSupport.park() - 调用之后等待等待其他线程调用 LockSupport.unpark(thread)

2.5 TIMED_WAITING - 超时等待

TIMED_WAITING 状态表示当前线程在限定时间内等待其他线程的一些动作,包括以下场景:

  • Thread.sleep()

  • Object.wait() - 指定等待时间

  • Thread.join() - 指定等待时间

  • LockSupport.parkNanos()

  • LockSupport.parkUntil()

2.6 TERMINATED - 终止

TERMINATED 表示终止状态,线程已经执行完成。

2.7 线程状态之间的流转

在这里插入图片描述

3. Java 线程个状态实例

3.1 NEW

/**
 * @author pointer
 * @date 2023-04-01 22:57:49
 */
public class NewThread {
    
    

    static class MyThread extends Thread {
    
    
        @Override
        public void run() {
    
    
            // do something
            System.out.println("继承 Thread 类,重写 run() 方法创建线程");
        }
    }

    public static void main(String[] args) {
    
    
        MyThread myThread = new MyThread();
        System.out.println(myThread.getState());
    }
}

输出结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_301.jdk ......
NEW

Process finished with exit code 0

3.2 RUNNABLE

/**
 * @author pointer
 * @date 2023-04-01 22:57:49
 */
public class NewThread {
    
    

    static class MyThread extends Thread {
    
    
        @Override
        public void run() {
    
    
            // do something
            System.out.println("继承 Thread 类,重写 run() 方法创建线程");
        }
    }

    public static void main(String[] args) {
    
    
        MyThread myThread = new MyThread();
        myThread.start();
        System.out.println(myThread.getState());
    }
}

输出结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_301.jdk ......
继承 Thread 类,重写 run() 方法创建线程
RUNNABLE

Process finished with exit code 0

3.3 BLOCKED

/**
 * @author pointer
 * @date 2023-04-01 22:57:49
 */
public class NewThread {
    
    

    static class MyBlockedThread extends Thread {
    
    
        @Override
        public void run() {
    
    
            // do something
            commonResource();
        }

        static synchronized void commonResource() {
    
    
            while(true) {
    
    
                // Infinite loop to mimic heavy processing
                // 'myBlockedThread1' won't leave this method
                // when 'myBlockedThread2' try to enter this
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
    
    
        MyBlockedThread myBlockedThread1 = new MyBlockedThread();
        MyBlockedThread myBlockedThread2 = new MyBlockedThread();
        myBlockedThread1.start();
        myBlockedThread2.start();
        Thread.sleep(1000);
        System.out.println(myBlockedThread2.getState());
        System.exit(0);
    }
}

输出结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_301.jdk ......
BLOCKED

Process finished with exit code 0

上述代码中,由于 myBlockedThread1 先抢占了类 commonResource 上的监视器锁,并且 myBlockedThread1 进入了无限循环,导致 myBlockedThread2 一直在等待获取监视器锁,因此打印 myBlockedThread2 的线程状态为 BLOCKED

3.4 WAITING

/**
 * @author pointer
 * @date 2023-04-01 22:57:49
 */
public class NewThread {
    
    

    static class MyThread1 extends Thread {
    
    
        @Override
        public void run() {
    
    
            System.out.println("MyThread1 begin run...");
            try {
    
    
                Thread.sleep(2000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            System.out.println("MyThread1 end run...");
        }
    }

    static class MyThread2 extends Thread {
    
    
        private Thread myThread1;

        public MyThread2(Thread myThread1) {
    
    
            this.myThread1 = myThread1;
        }

        @Override
        public void run() {
    
    
            System.out.println("MyThread2 begin run...");
            try {
    
    
                myThread1.join();
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            System.out.println("MyThread2 end run...");
        }
    }

    public static void main(String[] args) throws InterruptedException {
    
    
        MyThread1 myThread1 = new MyThread1();
        MyThread2 myThread2 = new MyThread2(myThread1);
        myThread1.start();
        myThread2.start();
        Thread.sleep(1000);
        System.out.println(myThread2.getState());
    }
}

输出结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_301.jdk ......
MyThread2 begin run...
MyThread1 begin run...
WAITING
MyThread1 end run...
MyThread2 end run...

Process finished with exit code 0

这里由于线程 MyThread2 调用了thread.join(),因此陷入 WAITING 状态。

3.5 TIMED_WAITING

/**
 * @author pointer
 * @date 2023-04-01 22:57:49
 */
public class NewThread {
    
    

    static class MyThread extends Thread {
    
    
        @Override
        public void run() {
    
    
            try {
    
    
                Thread.sleep(2000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
    
    
        MyThread myThread = new MyThread();
        myThread.start();
        Thread.sleep(1000);
        System.out.println(myThread.getState());
    }
}

输出结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_301.jdk ......
TIMED_WAITING

Process finished with exit code 0

这里由于线程 MyThread 调用了 Thread.sleep(2000),因此在等待期内的状态为 TIMED_WAITING

3.6 TERMINATED

/**
 * @author pointer
 * @date 2023-04-01 22:57:49
 */
public class NewThread {
    
    

    static class MyThread extends Thread {
    
    
        @Override
        public void run() {
    
    
            System.out.println("MyThread running begin..");
            System.out.println("MyThread running end..");
        }
    }

    public static void main(String[] args) throws InterruptedException {
    
    
        MyThread myThread = new MyThread();
        myThread.start();
        Thread.sleep(1000);
        System.out.println(myThread.getState());
    }
}

输出结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_301.jdk ......
MyThread running begin..
MyThread running end..
TERMINATED

Process finished with exit code 0

TERMINATED 是线程终止状态,线程完成执行或者异常终止后都会处于 TERMINATED 状态。

猜你喜欢

转载自blog.csdn.net/weixin_42201180/article/details/129903063