写点什么

Java 中多线程启动,为什么调用的是 start 方法,而不是 run 方法?

用户头像
云流
关注
发布于: 2021 年 02 月 18 日

继承 thread 类实现多线程

我们知道 java 有三种方式实现多线程,这里直接用继承的方式进行试验,其他方式同理。我们要做的是首先声明一个线程。然后去调用,最终根据结果归纳 run 和 start 的区别。

定义一个线程类。


class MyThread extends Thread {    private String title;    public MyThread(String title) {        this.title = title;    }    @Override    public void run() {        for(int x = 0; x < 5 ; x++) {            System.out.println(this.title + "运行,x = " + x);        }    }}复制代码
复制代码

在我们的主类中,起三个线程,看看调用的结果。代码如下:

public class ExtendsThread {
public static void main(String[] args) { new MyThread("线程A").start(); new MyThread("线程B").start(); new MyThread("线程C").start(); }}复制代码
复制代码

直接运行 main 方法。

观察结果我们发现,三个线程随机交替执行,取决于 cpu 的调度。

我们再使用 run 方法来进行调用,查看结果


public class ExtendsThread {    public static void main(String[] args) {        new MyThread("线程A").run();        new MyThread("线程B").run();        new MyThread("线程C").run();    }}复制代码
复制代码

结果如下:

看到这里细心的小伙伴发现了,这个 run 方法好像是顺序执行的啊!

的确是的,run 方法并不会实现多线程。而是顺序执行。那么为什么会产生这样的结果呢?


根本原因

查看 run 方法的源代码



我们发现 run 方法只是简单的调用了实现类的 run。没有进行任何的多线程处理。


查看 start 方法的源码



start 方法就不一样了。我们可以看到关键的代码就是 start0 方法。var1 理解为线程为启动,调用 start0 后,线程启动。继续追踪 start0.

这个是一个使用 jni 的 java 本地方法,jvm 根据不同的平台,调度的线程方法不同。

借用一张网上图,一目了然。

start() 方法调用 start0() 方法后,该线程并不一定会立马执行,只是将线程变成了可运行状态。具体什么时候执行,取决于 CPU ,由 CPU 统一调度。


总结

Java 中实现真正的多线程是 start 中的 start0() 方法,run() 方法只是一个普通的方法。


作者:经典鸡翅

链接:https://juejin.cn/post/6928581385854648334


用户头像

云流

关注

还未添加个人签名 2020.09.02 加入

还未添加个人简介

评论

发布
暂无评论
Java中多线程启动,为什么调用的是start方法,而不是run方法?