同一个线程对象能否多次调用start方法,搞清楚这个问题,首先需要了解线程的生命周期
一、线程生命周期
更多线程状态细节描述可查看Thread内部枚举类:State
从上图线程状态转换图可以看出:
- 新建(NEW)状态是无法通过其他状态转换而来的;
- 终止(TERMINATED)状态无法转为其他状态。
为何新建状态和终止状态不可逆转,接下来将通过Thread源码来分析
二、先通过一个正常程序来了解线程的执行过程:
public static void main(String[] args) {
//创建一个线程t1
Thread t1 = new Thread(() -> {
try {
//睡眠10秒,防止run方法执行过快,线程组被销毁
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
//第一次启动
t1.start();
}
- 当执行new Thread时,Thread构造方法会调用内部init方法做一些初始化工作,如设置线程组、目标方法、线程名称、堆栈大小、线程优先级等,线程状态是由
volatile
关键字修饰的threadStatus
控制的,初始值为0,即0表示新建状态(NEW); - 调用t1.start方法后,该方法会将调用本地方法start0,start0会创建一个新线程并修改Thread.threadStatus的值;
下面看下start方法源码:
/**线程成员变量,默认为0,volatile修饰可以保证线程间可见性*/
private volatile int threadStatus = 0;
/* 当前线程所属的线程组 */
private ThreadGroup group;
/**
* 同步方法,同一时间,只能有一个线程可以调用此方法
*/
public synchronized void start() {