Java启动线程的正确方式 & 为什么 run()方法不是启动线程的方式

文章目录

      • 启动线程方式的示例
      • start方法解读
      • 为什么 run()方法不是启动线程的方式

启动线程方式的示例

如下的代码示例. 使用lambda表达式 方式, 实现了Runnable 接口.
分别用 run方法和start方法去启动线程

public class StartAndRunMethod {

    public static void main(String[] args) {
        Runnable runnable = () -> {
            System.out.println(Thread.currentThread().getName());
        };
        runnable.run();
        new Thread(runnable).start();
    }

}

运行程序, 可以看到 run方法打印的线程名称为main线程, 并没有起一个新的线程. 而start方法才是启动了一个新的线程.
Java启动线程的正确方式 & 为什么 run()方法不是启动线程的方式_第1张图片

start方法解读

start方法的含义:

  1. 通知jvm在有空闲的情况下, 启动新的线程 . 至于什么时候去运行这个线程,是由线程的调度器去决定的 . 因此调用start方法的顺序, 并不能决定执行顺序.
  2. 由main线程去做一些准备工作,让新创建的线程能够去运行
    让线程处于就绪状态.
  3. 不能重复执行start方法
    两次执行start方法, 报错如下 . java.lang.IllegalThreadStateException非法的线程状态异常. 线程执行完毕, 变成终止状态, 不可能再次变成就绪状态, 因此抛出异常.
    Java启动线程的正确方式 & 为什么 run()方法不是启动线程的方式_第2张图片

start方法源码分析. start方法的源码, 会有如下的几个步骤:

  1. 启动柜新线程, 检查线程状态
  2. 加入线程组
  3. 调用start0()
    具体的源码如下.
    Java启动线程的正确方式 & 为什么 run()方法不是启动线程的方式_第3张图片
    启动可以看到 start0方法为native方法

为什么 run()方法不是启动线程的方式

Thread 类的run方法如下.
Java启动线程的正确方式 & 为什么 run()方法不是启动线程的方式_第4张图片
此run有两种情况

  1. 如果是实现Runnable接口的方式创建线程, 那么此处的run方法就会传入target
  2. 如果是继承Thread类的方式创建线程, 那么此run方法会完全被重写.

通过源码可以看出, 此方法完全没有创建线程的代码. 只是一个普通的方法而已. 不会像start方法, 去调用native方法, 去启动线程.

你可能感兴趣的:(Java多线程基础与核心)