首页 > 编程笔记 > Java笔记 阅读:25

Java线程的生命周期(附带实例)

在 Java 中,任何对象都有生命周期,线程也不例外。线程有新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Terminated)5 种状态,从新建到死亡称之为线程的生命周期,如下图所示。


图 1 线程的生命周期及状态转换

新建状态和就绪状态

当程序使用 new 关键字创建一个线程后,该线程处于新建状态,此时 JVM 给它分配一块内存,但不可运行。

当线程对象调用 start() 方法之后,该线程处于就绪状态,JVM 会为它创建方法调用栈和程序计数器。处于就绪状态的线程并没有开始运行,只是表示该线程可以运行了。获得 CPU 的使用权之后,线程即可开始运行。

注意,启动线程使用的是 start() 方法,而不是 run() 方法!如果直接调用 run() 方法,系统会把当前的线程识别为一个普通的对象,而 run() 方法也就是一个普通的方法,并不是线程的执行体。

接下来,通过案例来演示线程的启动。
public class Demo {
    public static void main(String[] args) throws InterruptedException {
        new MyThread().run();
        new MyThread().run();
    }
}

class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}
程序的运行结果如下:

main 0
main 1
main 2
main 3
main 4
main 0
main 1
main 2
main 3
main 4

程序中,线程创建之后直接调用 run() 方法,程序的运行结果是整个程序只有一个线程——主线程。启动线程的正确方法是调用线程的 start() 方法,而不是直接调用 run() 方法,否则就会变成单线程。

运行状态和阻塞状态

运行状态是指处于就绪状态的线程占用了 CPU,执行程序代码。并发执行时,如果 CPU 的占用时间超时,则会执行其他线程。只有处于就绪状态的线程才可以转换到运行状态。

阻塞状态是指线程因为一些原因放弃 CPU 使用权,暂时停止运行。当线程处于阻塞状态时,Java 虚拟机不会给线程分配 CPU,直到线程重新进入就绪状态,它才有机会转换到运行状态。

下面列举一下线程由运行状态转换成阻塞状态的原因,以及如何从阻塞状态转换成就绪状态:

注意,线程从阻塞状态只能进入就绪状态,不能直接进入运行状态。

死亡状态

线程会以如下方式结束,结束之后线程就处于死亡状态:
线程一旦转换为死亡状态,就不能运行且不能转换为其他状态。

注意,不要对处于死亡状态的线程调用 start() 方法,程序只能对新建状态的线程调用 start() 方法。判断线程是否死亡可以使用线程的 isAlive() 方法:当线程处于就绪、运行、阻塞这3种状态时,该方法返回 true;当线程处于新建和死亡状态时,该方法返回 false。

相关文章