6

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

 3 years ago
source link: http://www.cnblogs.com/jichi/p/14399907.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

前言

大年初二,大家新年快乐,我又开始码字了。写这篇文章,源于在家和基友交流的时候,基友问到了,我猛然发现还真是这么回事,多线程启动调用的都是start,那么为什么没人掉用run呢?于是打开我的idea,翻一波代码,带大家一探究竟。

继承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的调度。

aARnuen.png!mobile

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

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

结果如下:

6FzMV3e.png!mobile

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

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

根本原因

查看run方法的源代码

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

查看start方法的源码

eMbM7fM.png!mobile

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

Fj6nyaF.png!mobile

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

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

fM3mU3B.png!mobile

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

总结

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK