start()
使用start()才是真正意义上的启动一个新线程,调用start()之后,线程并不会立即进入到运行状态,而是会做一系列的准备工作,而是让自己处于就绪状态,此时会等待获取cpu资源,一旦获取到cpu资源,才会执行重写的run(),执行完后则会销毁线程。以下为线程调用start()的代码:
public static void main(String[] args) {
Runnable runnable = () -> {
System.out.println(Thread.currentThread().getName() + "被调用...");
};
new Thread(runnable).start();
}
执行结果如下,可以看到start()启动了一个子线程。
我们可以分析一下start()的源码,可以看出,当线程状态不为0时,会抛出IllegalThreadStateException,这就是为什么start方法不能执行两次的原因,最终,start方法会调用本地方法start0,以下为jdk8中start()的源码。
public synchronized void start() {
// 0为初始化状态
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) {
}
}
}
// 本地方法start0
private native void start0();
run()
run()和普通的方法没有什么区别,以下为run()执行的代码:
public static void main(String[] args) {
Runnable runnable = () -> {
System.out.println(Thread.currentThread().getName() + "被调用...");
};
runnable.run();
}
执行结果如下:
从执行结果可以看出,run方法并不是启动了一个子线程,而是直接执行了主线程。以下为run()方法执行的源码:
public void run() {
if (target != null) {
target.run();
}
}
总结
start()才能真正意义上的启动一个线程,才能去经历一个线程的生命周期。而run()只是一个普通的方法,并不会使用子线程去调用。start()不能执行两次,执行过一次之后,再执行就会抛出异常。