2.线程实现
原创
©著作权归作者所有:来自51CTO博客作者wx63560c7d74933的原创作品,请联系作者获取转载授权,否则将追究法律责任
1.实现线程的方式
Oracle官方文档阐述了两种实现线程的方式,一种是实现Runnable接口并重写run方法,另一种是继承Thread类并重写run方法,两种实现方式的代码分别如下所示。
/**
* 描述:使用Runnable接口的方式实现线程。
*/
public class RunnableStyle implements Runnable {
@Override
public void run() {
System.out.println("使用Runnable接口的方式实现线程");
}
public static void main(String[] args) {
Thread thread = new Thread(new RunnableStyle());
thread.start();
}
}
/**
* 描述:使用继承Thread类的方式实现线程。
*/
public class ThreadStyle extends Thread{
@Override
public void run() {
System.out.println("使用继承Thread类的方式实现线程");
}
public static void main(String[] args) {
ThreadStyle thread = new ThreadStyle();
thread.start();
}
}
2.两种实现方式的区别
官方建议使用Runnable方式实现线程,原因主要有以下三点。
- Runnable可避免Java单继承的缺陷。如果一个类本身已经继承一个父类,那么该类将无法通过继承Thread类的方式实现线程。
- Runnable可避免子类继承Thread类中除run和start以外的方法。实现线程任务的run方法,应该要将其从该类中解耦出来。
- Runnable可以有共享数据。使用同一个Runnable构造的不同线程之间是可以共享数据的,而Thread类不能共享数据。
3.实现细节
从上述两种实现方式的代码来看,本质上,都是通过Thread类的构造方法来创建线程的,只是一个传递了Runnable实例,一个没有。如果继承Thread类,那么run方法会被完全覆盖,执行子类的run方法,里面的判断逻辑将不会执行。而实现Runnable接口时,传入Runnable实例,run方法里的判断逻辑将会被执行,调用的是实例的run方法。具体源代码如下所示。
public interface Runnable {
public abstract void run();
}
public class Thread implements Runnable {
private Runnable target;
private void init(ThreadGroup g, Runnable target, String name, long stackSize) {
init(g, target, name, stackSize, null, true);
}
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
@Override
public void run() {
if (target != null) {
target.run();
}
}
}
4.思考题
分析以下代码执行结果并思考原因。
/**
* 描述:同时使用Runnable和Thread两种实现线程的方式。
*/
public class BothRunnableAndThread {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("使用Runnable接口的方式实现线程");
}
}){
@Override
public void run() {
System.out.println("使用继承Thread类的方式实现线程");
}
}.start();
}
}
代码运行结果如下所示,由此可知,当同时使用两种线程实现方式时,执行的是Thread类的run方法,原因是当Thread类的run方法被覆盖时, target.run()便不会被执行,即Runnable的run方法不会被执行。