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

您所在的位置:网站首页 为什么调用start方法会执行run方法 Java 多线程启动为什么调用 start() 方法而不是 run() 方法?

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

2024-07-15 10:15:43| 来源: 网络整理| 查看: 265

多线程在工作中多多少少会用到,启动 多线程调用的是 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 跨平台说起,看下面这张图:

image

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

我们又知道 Java 是跨平台的,可以在不同系统上运行,每个系统的 CPU 调度算法不一样,所以就需要做不同的处理,这件事情就只能交给 JVM 来实现了,start0() 方法自然就表标记成了 native。

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



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭