线程的最佳实践一:不覆写Thread.start()方法

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该线程。

 

 

参考书籍《编写高质量代码》

你可能感兴趣的:(书籍笔记)