java 多线程 run start_Java 多线程发动为什么调用 start() 办法而不是 run() 办法?

本文解释了Java中为何启动多线程时调用start()方法而非run()方法。通过对比两种方法的作用及源码分析,揭示了start()方法如何通过start0()本地方法创建并启动新线程。

Java 多线程发动为什么调用 start() 办法而不是 run() 办法?

多线程在工作中多多少少会用到,咱们知道发动多线程调用的是 start() 办法,而不是 run() 办法,你知道原因吗?

在讨论这个问题之前,咱们先来了解一些多线程的基础知识~

线程的状况

Java 中,界说了 6 种线程状况,在 Thread 类能够找到:

// 为了节省空间,我删除了注释

public enum State {

NEW,//初始状况

RUNNABLE,//运转状况

BLOCKED,// 堵塞状况

WAITING,//等候状况

TIMED_WAITING,//超时等候状况

TERMINATED;//停止状况

}

这 6 种状况之间的相关,能够看下面这张图:

这张图描绘的仍是十分详细的,结合这张图,来说说这几种状况别离代表着什么意思:

1、NEW 表明线程创立成功,但没有运转,在 new Thread 之后,没有 start 之前,线程都处于 NEW 状况;

2、RUNNABLE 表明线程正在运转中,当咱们运转 strat 办法,子线程被创立成功之后,子线程的状况变成 RUNNABLE;

3、TERMINATED 表明线程现已运转完毕,子线程运转完结、被打断、被间断,状况都会从 RUNNABLE 变成 TERMINATED;

4、BLOCKED 表明线程被堵塞,假如线程正好在等候取得 monitor lock 锁,比如在等候进入 synchronized 润饰的代码块或办法时,会从 RUNNABLE 变成 BLOCKED;

5、 WAITING 和 TIMED_WAITING 都表明等候,现在在遇到 Object#wait、Thread#join、

LockSupport#park 这些办法时,线程就会等候另一个线程履行完特定的动作之后,才能结

束等候,只不过 TIMED_WAITING 是带有等候时间的;

优先级

优先级代表线程履行的时机的巨细,优先级高的或许先履行,低的或许后履行。

在 Java 源码中,优先级从低到高别离是 1 到 10,线程默许 new 出来的优先级都是 5,源码如下:

/**

The minimum priority that a thread can have.

*/

public final static int MIN_PRIORITY = 1;

/**

The default priority that is assigned to a thread.

*/

public final static int NORM_PRIORITY = 5;

/**

The maximum priority that a thread can have.

*/

public final static int MAX_PRIORITY = 10;

线程得创立办法

咱们创立多线程有两种办法,一种是承继 Thread 类,另一种是完结 Runnable 接口。两种办法的运用,如下所示:

1、承继 Thread,成为 Thread 的子类

public class MyThread extends Thread{

@Override

public void run() {

System.out.println("我是经过承继 Thread 类完结的~");

}

public static void main(String[] args) {

MyThread thread = new MyThread();

// 发动线程

thread.start();

}

}

2、完结 Runnable 接口

public class MyThread1 {

public static void main(String[] args) {

Thread thread = new Thread(new Runnable() {

@Override

public void run() {

System.out.println("我是经过 runnable 办法完结的~");

}

});

// 发动线程

thread.start();

}

}

不论运用哪一种办法,发动线程都是thread.start()办法,假如你做过试验的话,你会发现 thread.run()也能够履行,为什么就必定需求调用thread.start()办法呢?

先说说定论:首要经过目标.run()办法能够履行办法,可是不是运用的多线程的办法,便是一个一般的办法,要想完结多线程的办法,必定需求经过目标.start()办法。

想要弄理解一个问题,最好的办法便是从源码下手,咱们也从这两个办法的源码开端,先来看看 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".

*/

// 没有初始化,抛出反常

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 办法

// 履行完结之后,新的线程现已在运转了

start0();

// 主线程履行

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 */

}

}

}

start 办法的源码也没几行代码,注释也比较详细,最主要的是 start0() 办法,这个后边在解说。再来看看 run() 办法的源码:

@Override

public void run() {

// 简略的运转,不会新起线程,target 是 Runnable

if (target != null) {

target.run();

}

}

run() 办法的源码就比较简略的,便是一个一般办法的调用,这也印证了咱们上面的定论。

接下来咱们就来说一说这个 start0() 这个办法,这个是真实完结多线程的要害,start0() 代码如下:

private native void start0();

start0 被符号成 native ,也便是本地办法,并不需求咱们去完结或许了解,为什么 start0() 会符号成 native?

这个要从 Java 跨渠道说起,看下面这张图:

start() 办法调用 start0() 办法后,该线程并不必定会立马履行,仅仅将线程变成了可运转状况。详细什么时候履行,取决于 CPU ,由 CPU 一致调度。

咱们又知道 Java 是跨渠道的,能够在不同体系上运转,每个体系的 CPU 调度算法不一样,所以就需求做不同的处理,这件工作就只能交给 JVM 来完结了,start0() 办法天然就表符号成了 native。

最终,总结一下,Java 中完结真实的多线程是 start 中的 start0() 办法,run() 办法仅仅一个一般的办法。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值