如果想要清楚的明确这个问题,我们需要先知道线程的一些基本知识(线程生命周期的不同状态)。
线程状态被封装在java.lang.Thread.State中,State是Thread的内部枚举类。
以下源代码展示
public enum State {
/**
* 尚未启动的线程的线程状态。
*/
NEW,
/**
*该线程以及在JVM中执行,由于执行需要计算资源,它可能正在运行,也可能还在等待系统分配它CPU片段,在就绪队列里面排队
*/
RUNNABLE,
/**
* 线程处于锁等待状态
*/
BLOCKED,
/**
* 线程处于条件等待状态,触发条件后唤醒,比如wait()\notify()
*/
WAITING,
/**
* 比WAITING多了一个超时条件触发
*/
TIMED_WAITING,
/**
* 线程执行结束
*/
TERMINATED;
}
明确了线程的生命周期状态后,我们来看线程两次执行start()方法会怎么样?
public class ThreadDemo extends Thread{
public int count;
@Override
public void run() {
System.out.println("线程被调用" + (++count) + "次");
}
}
public class ThreadTest {
public static void main(String[] args) {
ThreadDemo threadDemo = new ThreadDemo();
threadDemo.start(); //第一次调用start()
threadDemo.start(); //第二次调用start()
}
}
执行结果
我们会发现执行结果报了IllegalThreadStateException的错误,翻译来说是不合法的线程状态错误。
总结来说当我们第一次调用start()方法的时候,线程的状态可能处于终于或者非NEW状态,再调用一次start(),相当于让这个正在运行的线程重新运行,不管从线程的安全性角度,还是从线程本身的执行逻辑,都是不合理的。因此java代码执行的时候为了避免这个问题的发生,在线程运行的时候会判断当前线程的运行状态了。