【Kill Thread Part.1】启动线程的正确姿势
一、start()和run()的比较
1、测试代码
/**
* 描述:对比start和run两种启动线程的方式
*/
public class StartAndRunMethod {
public static void main(String[] args) {
Runnable runnable = () -> {
System.out.println(Thread.currentThread().getName());
};
//main,是当前主函数这个线程去调用的。
runnable.run();
//Thread-0
new Thread(runnable).start();
}
}
运行结果
2、start()方法原理解读
①start()方法含义
-
启动新线程
- 调用start()方法就是告诉JVM有一个线程要启动了,但是具体线程运行没有,还需要线程调度的单元负责,并不是说执行start()方法之后线程就行开始运行了。
-
准备工作
- 准备线程控制块等资源
-
不能重复start()
-
/** * 描述:演示不能两次调用start方法,否则会报错 */ public class CantStartTwice { public static void main(String[] args) { Thread thread = new Thread(); thread.start(); thread.start(); } }
-
②start()源码解析
- 启动新线程检查线程状态
- threadStatus是什么?
- threadStatus是什么?
- 加入线程组
- 调用start0() Native方法
3、run()方法原理解读
- 这个方法在上一节已经讲解过了,就是重写与否,是否传入了Runnable接口的实现类。
- 要想启动线程,不能直接调用run方法,而是要用start()方法间接的调用run()方法。
二、常见面试问题
1、一个线程两次调用start()方法会出现什么情况?为什么?
- 首先,会抛出异常
- 为什么?
- 深入start()方法的源码
- 扩展
- 回答线程生命周期的几个状态
2、既然start()方法会调用run()方法,为什么我们选择调用start()方法,而不是直接调用run()方法呢?
- 因为调用start()方法才会真正意义上的启动线程,会经历线程的声明周期。
- 而直接调用run()方法,只是一个普通的方法,并不会用子线程去调用。