并发基础之正确启动多线程
2019-11-05 16:02:57来源:博客园 阅读 ()
并发基础之正确启动多线程
start方法和run方法比较
很多人包括我自己也以前也认为run和start方法都可以启动一个线程,并且两者的功能都差不多,然后在学习的过程中认识到这是错误的,他们之间是截然不同的。先来看一段演示代码:
/**
* @author Chen
* @Description start()和run()方法比较
* @create 2019-11-05 22:01
*/
public class StartAndRunMethod {
public static void main(String[] args) {
//使用run方法
Runnable runnable = ()-> System.out.println(Thread.currentThread().getName());
runnable.run();
//使用start方法
new Thread(runnable).start();
}
}
输出结果:
main
Thread-0
可以看到,执行run方法的线程是主线程,而执行start方法的才是一个新的子线程。
start方法解读
我们都知道start方法就是启动一个新线程,其实真是情况是start方法执行过程中会涉及到两个线程,一个是主线程,另一个是新的子线程,当调用start方法是,子线程并不会马上启动起来,子线程会获取除了cpu以外的一些资源,进入就状态,等待CPU的调用。至于什么时候调用,这个就不是我们所能决定的了,而是线程调度器来决定的。所以有一些先运行start方法的线程可能会在比后调用start方法的线程启动的慢。
当我们重复调用两次start方法会发生什么?
会抛出一个异常IllegalThreadStateException(非法的线程状态),其实线程一旦执行,就会进入runnable状态,一旦执行完毕,就会进入结束状态,不会在返回回去。
接下来我们在来仔细看看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();
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()
中,首先会检查线程的状态,判断threadStatus
是不是等于0,也就是判断是不是一个新启动的线程,这是执行两次start()
抛出异常的原因。(在线程刚刚被初始化的时候默认的状态为0)
然后又做了一个加入线程组这个行为,然后又执行了个start0的native方法。
run方法解读
其实run方法比较简单,只有三行代码:如果target也就是传入的接口不为空,就执行重写的run方法的内容,否则就执行传入的run方法的内容。
@Override
public void run() {
if (target != null) {
target.run();
}
}
所以当我们执行run方法的时候,它就会作为一个普通的方法,和我们自己写的一样,所以控制台打印出来的是一个主线程。
所以我们想启动一个新线程不能直接调用run方法,而是应该调用start方法来间接调用run方法。
原文链接:https://www.cnblogs.com/chen88/p/11802279.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:SpringBoot依赖
- 04.Java基础语法 2020-06-11
- 1-Java基础回顾整理_01 2020-06-10
- Java基础语法菜鸟教程笔记 2020-06-10
- Java基础复习——类和对象 2020-06-09
- 计算机基础到底是哪些基础?为什么很重要! 2020-06-08
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash