1.在java中实现线程有两种方式,一种是实现Runnable接口;一种是集成Thread类。无论是那一种,我们都会覆写run()方法,在这个方法里可以完成我们需要线程做的事。而不是覆写start()方法,对于java线程而言,调用start()方法时,该方法会调用我们线程的run()方法,那么这是怎么做到的呢?
2.Thread类的源码如下:
public synchronized void start() {
//判断线程的状态,线程必须是未启动的
if (threadStatus != 0 || this != me)
throw new IllegalThreadStateException();
group.add(this);
//分配栈内存,启动线程,运行run方法
start0();
//在启动前设置了停止状态
if (stopBeforeStart) {
stop0(throwableFromStop);
}
}
private native void start0();
由源码可以看出,关键部分在本地方法start0,它实现了启动线程,分配栈内存,运行run方法,修改线程状态的职责。这些都是由jvm负责的,如果覆盖了start方法,则失去了jvm对线程的管理。线程的start方法本身就将线程交给jvm管理了,使得程序员只需要关注线程的逻辑,而不用手动管理线程,这个方法为程序员提供了很多便利,没有理由要覆写这个方法。如果一定要覆写,那么一定要像这样:
@override
public void start(){
super.start();
//....
}
不过覆写后没有什么实际意义。
3.线程的最佳实践之一就是覆写run方法,而不应该覆写start方法。
4.补充:由start方法的源码可以看出,即使一个线程在启动的时候已经是stop状态了,线程依然会启动,然后再stop。start方法的逻辑是先start一个线程,再校验该线程状态是否是stop,如果是再stop该线程。
参考书籍《编写高质量代码》