Java Thread之start和run方法的区别
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11421515.html
start
用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,run方法运行结束,此线程随即终止。
start方法源码示例

一个 Java 线程的创建本质上就对应了一个本地线程(native thread)的创建,两者是一一对应的。
关键问题是:本地线程执行的应该是本地代码,而 Java 线程提供的线程函数(run)是 Java 方法,编译出的是 Java 字节码。
所以, Java 线程其实提供了一个统一的线程函数,该线程函数通过 Java 虚拟机调用 Java 线程方法 , 这是通过 Java 本地方法 start0 调用来实现的。
也就是新创建的线程启动调用native start0方法,而这些native方法的注册是在Thread对象初始化的时候完成的

Thread 类有个 registerNatives 本地方法,该方法主要的作用就是注册一些本地方法供 Thread 类使用,如 start0(),stop0() 等等,可以说,所有操作本地线程的本地方法都是由它注册的。
这个方法放在一个 static 语句块中,当该类被加载到 JVM 中的时候,它就会被调用,进而注册相应的本地方法。(查看本地方法的源码需要前往 http://jdk.java.net/java-se-ri/8下载openjdk的源代码)
而本地方法 registerNatives 是定义在 Thread.c 文件中的。Thread.c 是个很小的文件,它定义了各个操作系统平台都要用到的关于线程的公用数据和操作,如下:

可以看出 Java 线程调用 start->start0 的方法,实际上会调用到 JVM_StartThread 方法,而 JVM_StartThread 最终调用的是 Java 线程的 run 方法。
在 jvm.cpp 中,有如下代码段:

这里 JVM_ENTRY 是一个宏,用来定义 JVM_StartThread 函数,可以看到函数内创建了真正的平台相关的本地线程,其线程函数是 thread_entry,如下:

可以看到调用了 vmSymbols::run_method_name 方法,而 run_method_name 是在 vmSymbols.hpp 用宏定义的:

run
run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。
run方法源码示例

分别测试start和run
package org.fool.test.thread;
public class ThreadTest {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " invoked...");
}
});
thread.start();
//thread.run();
}
}
先运行thread.start()
Thread- invoked...
注释调thread.start()方法,运行thread.run()
main invoked...
Summary
start方法可启动多线程
run方法只是thread的一个普通方法调用,还是在主线程里执行,是不会开启多线程的
Java Thread之start和run方法的区别的更多相关文章
- Java -- Thread中start和run方法的区别
一.认识Thread的 start() 和 run() 1.start(): 我们先来看看API中对于该方法的介绍: 使该线程开始执行:Java 虚拟机调用该线程的 run 方法. 结果是两个线程并发 ...
- 创建线程的一般方式和匿名内部类方式对比——继承thread类,重写run()方法
第一种:继承thread类,重写run()方法 一般方式:Demo01.java /** * 创建线程的第一种方式:继承thread类,重写run()方法 * * @author :liuqi * @ ...
- 创建多线程的第一种方式——创建Thread子类和重写run方法
创建多线程的第一种方式——创建Thread子类和重写run方法: 第二种方式——实现Runnable接口,实现类传参给父类Thread类构造方法创建线程: 第一种方式创建Thread子类和重写run方 ...
- Python之路(第四十二篇)线程相关的其他方法、join()、Thread类的start()和run()方法的区别、守护线程
一.线程相关的其他方法 Thread实例对象的方法 # isAlive(): 返回线程是否活动的. # getName(): 返回线程名. # setName(): 设置线程名. threadin ...
- 认识多线程中start和run方法的区别?
一.认识多线程中的 start() 和 run() 1.start(): 先来看看Java API中对于该方法的介绍: 使该线程开始执行:Java 虚拟机调用该线程的 run 方法. 结果是两个线程并 ...
- 调用start()方法和直接调用run()方法的区别
调用start()方法和直接调用run()方法的区别 新建一个线程,只需要使用new关键字创建一个线程对象,并且调用start()方法即可. Thread thread = new Thread(); ...
- 线程的状态有哪些,线程中的start与run方法的区别
线程在一定条件下,状态会发生变化.线程一共有以下几种状态: 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法. ...
- 0040 Java学习笔记-多线程-线程run()方法中的异常
run()与异常 不管是Threade还是Runnable的run()方法都没有定义抛出异常,也就是说一条线程内部发生的checked异常,必须也只能在内部用try-catch处理掉,不能往外抛,因为 ...
- Java中start和run方法的区别
一.问题引入 说到这两个方法就不得不说多线程,说到多线程就不得不提实现多线程的两种方式继承Thread类和实现Runable接口,下面先看这两种方式的区别. 二. Java中实现多线程 ...
随机推荐
- hover()函数的用法
定义和用法 hover() 方法规定当鼠标指针悬停在被选元素上时要运行的两个函数. 实例 当鼠标指针悬停在上面时,改变 <p> 元素的背景颜色: $("p").hove ...
- Halo(十)
Spring Converter(转换器) @FunctionalInterface public interface Converter<S, T> { //一对一转换 @Nullabl ...
- mobx学习笔记04——mobx常用api
1 可观察的数据(observable) observable是一种让数据的变化可以被观察的方法. 那些数据可被观察? -原始类型 String.Number.Boolean.Symbol -对象 - ...
- c++ ofstream使用方法
ofstream是从内存到硬盘,ifstream是从硬盘到内存,流缓冲即是内存空间. 插入器<< : 向流输出数据. cout << "test!" &l ...
- visual studio code的使用
1.添加代码片段 参考:https://blog.csdn.net/qq_36370731/article/details/83014439 2.在vscode上运行Git 先打开vscode内置的G ...
- 107、TensorFlow变量(三)
创建秩为1的张量 # create a rank1 tensor object import tensorflow as tf mystr = tf.Variable(["Hello&quo ...
- /proc/interrupts /proc/stat 查看中断信息
/proc/interrupts列出当前所以系统注册的中断,记录中断号,中断发生次数,中断设备名称 如下图:从左至右:中断号 中断次数 中断设备名称 从上图可知中断号为19的arch_timer ...
- oracle函数自治事务解决不能增改删的语句操作
CREATE OR REPLACE FUNCTION SEQ3 (v_bname in VARCHAR2) return NUMBER is pragma autonomous_transaction ...
- 2.tensorflow——Softmax回归
import numpy as np import tensorflow as tf import matplotlib.pyplot as plt from tensorflow.examples. ...
- Day 45 Mysql 数据库练习题二
1.表关系 注意:创建表时,根据合理性设置字段的长度和类型. 2.下面:开始你的表演 1.查询所有人员信息 select * from ren 2.只查询人员的姓名和年龄 select name, ...