【Kill Thread Part.1-2】启动线程的正确姿势

【Kill Thread Part.1】启动线程的正确姿势

一、start()和run()的比较

1、测试代码

/**
 * 描述:对比start和run两种启动线程的方式
 */
public class StartAndRunMethod {
    public static void main(String[] args) {
        Runnable runnable = () -> {
            System.out.println(Thread.currentThread().getName());
        };
        //main,是当前主函数这个线程去调用的。
        runnable.run();

        //Thread-0
        new Thread(runnable).start();
    }
}

运行结果

image-20220118182945053

2、start()方法原理解读

①start()方法含义

  • 启动新线程

    • 调用start()方法就是告诉JVM有一个线程要启动了,但是具体线程运行没有,还需要线程调度的单元负责,并不是说执行start()方法之后线程就行开始运行了。
  • 准备工作

    • 准备线程控制块等资源
  • 不能重复start()

    • /**
       * 描述:演示不能两次调用start方法,否则会报错
       */
      public class CantStartTwice {
          public static void main(String[] args) {
              Thread thread = new Thread();
              thread.start();
              thread.start();
          }
      }
      
    • image-20220118183733720

②start()源码解析

  • 启动新线程检查线程状态
    • image-20220118184146247
    • threadStatus是什么?
      • image-20220118192130242
  • 加入线程组
    • image-20220118192602168
  • 调用start0() Native方法

image-20220118192545560

3、run()方法原理解读

  • 这个方法在上一节已经讲解过了,就是重写与否,是否传入了Runnable接口的实现类。
  • 要想启动线程,不能直接调用run方法,而是要用start()方法间接的调用run()方法。

二、常见面试问题

1、一个线程两次调用start()方法会出现什么情况?为什么?

  • 首先,会抛出异常
  • 为什么?
    • 深入start()方法的源码
  • 扩展
    • 回答线程生命周期的几个状态

2、既然start()方法会调用run()方法,为什么我们选择调用start()方法,而不是直接调用run()方法呢?

  • 因为调用start()方法才会真正意义上的启动线程,会经历线程的声明周期。
  • 而直接调用run()方法,只是一个普通的方法,并不会用子线程去调用。
posted @ 2022-01-18 19:35  DarkerG  阅读(37)  评论(0编辑  收藏  举报