线程的生命周期

一、线程的生命周期

线程一个完整的生命周期要经历如下五种状态:

  • 新建:当一个Thread类或者其子类的对象被声明并创建时,新生的线程对象处于新建状态
  • 就绪:处于新建状态的西纳城被start()之后,将进入线程队列等待CPU时间片
  • 运行:当就绪的线程被调度并会的处理器资源时,便进入运行状态,run()方法定义了线程的操作和功能
  • 阻塞:在某种特殊情况下,被人为挂起挥着执行输入输出操作时,让出CPU并临时中止自己的执行,进入阻塞状态
  • 死亡:线程完成了它的全部工作或者线程被提前强制性的中止

二、线程的生命周期状态转换图

三、start方法源码分析

上面的API文档是说,当我们调用线程的start方法时,JVM会调用当前线程的run()方法。这样就同时有两个线程在运行(当前线程和调用线程start()方法的线程)

此外,同一个线程不能调用start()方法两次,否则会报错,IllegalThreadStateException 。

(1)线程调用两次start()方法测试

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

    Thread thread = new Thread(() -> {
        System.out.println("hello");
    });

    thread.start();
    thread.start();

}

输出结果:

(2)start()内部源码分析

public synchronized void start() {
     /**
     * This method is not invoked for the main method thread or "system"
     * group threads created/set up by the VM. Any new functionality added
     * to this method in the future may have to also be added to the VM.
     *
     * A zero status value corresponds to state "NEW".
     */

     //状态校验 0:NEW 新建状态
    if (threadStatus != 0)
        throw new IllegalThreadStateException();

    /* Notify the group that this thread is about to be started
     * so that it can be added to the group's list of threads
     * and the group's unstarted count can be decremented. */
   
     group.add(this);   // 添加进线程组 

    boolean started = false;
    try {
        start0(); //调用native方法执行线程run方法
        started = true;
    } finally {
        try {
            if (!started) {
                group.threadStartFailed(this);  //启动失败,从线程组中移除当前前程。
            }
        } catch (Throwable ignore) {
            /* do nothing. If start0 threw a Throwable then
              it will be passed up the call stack */
        }
    }
}

四、Thread的run()与start()的区别?

该部分转自Thread的run()与start()的区别

调用start()后,线程会被放到等待队列,等待CPU调度,并不一定要马上开始执行,只是将这个线程置于可动行状态。然后通过JVM,线程Thread会调用run()方法,执行本线程的线程体。先调用start后调用run,这么麻烦,为了不直接调用run?就是为了实现多线程的优点,没这个start不行。

  • start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。 然后通过此Thread类调用方法run()来完成其运行操作的, 这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调度其它线程。
  • run()方法当作普通方法的方式调用。程序还是要顺序执行,要等待run方法体执行完毕后,才可继续执行下面的代码; 程序中只有主线程——这一个线程, 其程序执行路径还是只有一条, 这样就没有达到写线程的目的。

记住:多线程就是分时利用CPU,宏观上让所有线程一起执行 ,也叫并发。

 

原文地址:https://www.cnblogs.com/ch-forever/p/10747235.html