多线程 start 和 run 方法到底有什么区别?
昨天栈长介绍了《Java多线程可以分组,还能这样玩!》线程分组的妙用。今天,栈长会详细介绍 Java 中的多线程 start() 和 run() 两个方法,Java 老司机请跳过,新手或者对这两个不是很理解的可以继续往下看。
首先要知道实现多线程最基本的两种方式:
1、继承 java.lang.Thread 类;
2、实现 java.lang.Runnable接口;
其中 Thread 类也是实现了 Runnable 接口,而 Runnable 接口定义了唯一的一个 run() 方法,所以基于 Thread 和 Runnable 创建多线程都需要实现 run() 方法,是多线程真正运行的主方法。
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
而 start() 方法则是 Thread 类的方法,用来异步启动一个线程,然后主线程立刻返回。该启动的线程不会马上运行,会放到等待队列中等待 CPU 调度,只有线程真正被 CPU 调度时才会调用 run() 方法执行。
所以 start() 方法只是标识线程为就绪状态的一个附加方法,以下 start() 方法的源码,其中 start0() 是一个本地 native 方法。
public synchronized void start() {
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
boolean started = false;
try {
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() 方法被标识为 synchronized 的,即为了防止被多次启动的一个同步操作。
那么你会问了,为什么要有两个方法,直接用一个 run() 方法不就行了吗!? 还真不行,如果直接调用 run() 方法,那就等于调用了一个普通的同步方法,达不到多线程运行的异步执行,来看下面的例子。
/**
* 微信公众号:Java技术栈
*/
public static void main(String[] args) {
Thread thread = new Thread(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Java技术栈");
});
long start = System.currentTimeMillis();
thread.start();
System.out.println(System.currentTimeMillis() - start);
start = System.currentTimeMillis();
thread.run();
System.out.println(System.currentTimeMillis() - start);
}
程序输出:
0
Java技术栈
3000
Java技术栈
从程序输出结果可以看出,启动 start 方法前后只用了 0 毫秒,而启动 run 方法则阻塞了 3000 毫秒等程序执行完再继续执行,这就是同步与异步的一个最重要的区别。
看完这篇,你应该对 start 和 run 方法有了一个大概的掌握吧,再也不怕面试官问你这两个的区别了吧!
动手转发给更多的朋友吧!
更多 Java 多线程技术文章请在Java技术栈微信公众号后台回复关键字:多线程。
本文原创首发于微信公众号:Java技术栈(id:javastack),关注公众号在后台回复 "多线程" 可获取更多,转载请原样保留本信息。
多线程 start 和 run 方法到底有什么区别?的更多相关文章
- Python 多线程 start()和run()方法的区别(三)
上一篇文章最后只是简单介绍了start()方法和run()方法,这篇文章再详细地看下start()和run()的区别. 在实例调用的函数中加入打印当前线程的名字,分别用start()方法和run()方 ...
- java 多线程 start方法 run方法 简单介绍。
一 start开启一个多线程, run 只是一个内部的方法. package com.aaa.threaddemo; /* * start方法的作用? * 在 Java中启动多线程调用的是start方 ...
- JAVA多线程中start方法与run方法区别
start()方法告诉jvm该线程准备运行,jvm通过调用任务的run()方法执行任务. 一个任务类必须实现Runnable接口,而任务必须从线程运行. 实现Runnable接口后必须重写run()方 ...
- 认识多线程中start和run方法的区别?
一.认识多线程中的 start() 和 run() 1.start(): 先来看看Java API中对于该方法的介绍: 使该线程开始执行:Java 虚拟机调用该线程的 run 方法. 结果是两个线程并 ...
- 创建多线程的第一种方式——创建Thread子类和重写run方法
创建多线程的第一种方式——创建Thread子类和重写run方法: 第二种方式——实现Runnable接口,实现类传参给父类Thread类构造方法创建线程: 第一种方式创建Thread子类和重写run方 ...
- Java多线程-run方法与start方法的区别
package com.interview; /** * java多线程的两种实现方式以及run.start方法的区别 * @author MEI.LIU * */ public class Thre ...
- java中多线程执行时,为何调用的是start()方法而不是run()方法
Thead类中start()方法和run()方法的区别 1,start()用来启动一个线程,当调用start()方法时,系统才会开启一个线程,通过Thead类中start()方法来启动的线程处于就绪状 ...
- Java 多线程启动为什么调用 start() 方法而不是 run() 方法?
多线程在工作中多多少少会用到,我们知道启动多线程调用的是 start() 方法,而不是 run() 方法,你知道原因吗? 在探讨这个问题之前,我们先来了解一些多线程的基础知识~ 线程的状态 Java ...
- Java中多线程启动,为什么调用的是start方法,而不是run方法?
前言 大年初二,大家新年快乐,我又开始码字了.写这篇文章,源于在家和基友交流的时候,基友问到了,我猛然发现还真是这么回事,多线程启动调用的都是start,那么为什么没人掉用run呢?于是打开我的ide ...
随机推荐
- skyline开发——读取Shapefile要素属性
double len; IFeatures66 features = featureLayer.FeatureGroups.Polyline.GetCurrentFeatures(); foreach ...
- Filezilla server配置FTP服务器中的各种问题与解决方法
转至;https://www.jb51.net/article/122171.htm 安装文件以及补丁下载 公司很多资料需要通过ftp上传,那么就需要配置一个FTP服务器,找了一台Windows服务器 ...
- JS獲取URL的參數
function GetQueryString(name) { var reg = new RegExp("(^|&)"+ name +"=([^&]*) ...
- asp.net core部署到iis中出现 HTTP Error 502.5 - Process Failure的问题
环境是windows Server2012 问题的原因是缺少文件:api-ms-win-crt-runtimel1-1-0.dll, dotnet 启动程序失败. 解决方案1: 安装系统补丁: 20 ...
- CentOS 7 下安装oracle 11g碰到的一些问题
OUI预检查时会报错,安装时会报两个不符合项目 1 compat-libstdc++ 提示未安装 奇怪这个,yum install compat-libstdc++ 老是提示找不到包,其实正确的安装方 ...
- mongodb内嵌文档的javaapi,增删改查
数据结构: {"_id" : "000000001", //Mongodb默认主键 "UID" : "000000001&quo ...
- 地磁应用中的低功耗无线数传模块xbee PRO S2C
地球上每一个地理坐标点,在一段时间内磁场强度是恒定的,当车辆这种铁磁物质经过这个点时,对这个点的磁场强度产生一个连续的扰动,通过磁传感器采样数据与初始采样数据(该点的地球磁场值)进行对比,其差值为车辆 ...
- Sorl 4.10 入门合集
Sorl4.10 + Tomcat 7.0 win7环境下的安装 1.首先是到apache官网下载sorl 4.10 ,解压 2.进入路径\solr-4.10.4\example\webapps,拷 ...
- Oracle中将Clob字段转换成字符串
1. 利用dbms_lob.substr()方法可将对应字段转换成字符串如下 select dbms_lob.substr(content) from NEWS 该方法有个缺点,当content字段长 ...
- 2019浙江省赛B zoj4101 Element Swapping(推公式)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=6003 题意 \(数组a通过交换一对数字,得到了b数组,给出x=\sum^n_{ ...