在 Java 中,常用的创建线程方式有两种,一种是继承 Thread 类;另一种是直接实现 Runnable 接口,然后 @Override 其中的 run 方法。今天我们就来探究一下这两种方式的异同点吧。
Runnable 和 Thread 的关系
说穿了,Thread 类就是 Java 官方给我们提供的一种 Runnable 接口的实现。
Runnable 是一个接口
Runnable 源码
1 | public interface Runnable { |
Thread 是一个实现了 Runnable 接口的类
Thread 部分源码
1 | public class Thread implements Runnable { |
所以这两种创建线程的方式的异同就变成了继承类和实现接口之间的区别。一般来说,当 Java 开发中遇到多线程的情况,建议以实现 Runnable 接口为主,因为实现 Runnable 接口相比继承 Thread 类有如下优势:
- 可以避免由于 Java 的单继承特性而带来的局限;
- 适合多个线程去处理同一资源的情况;
举个例子
下面以经典的卖票程序为例,来说明二者的区别。
继承 Thread 类实现
1 | package com.thread; |
测试程序
1 | package com.thread; |
运行结果
很明显,这里虽然启用了三个线程,但三个线程各自完成了 10 次的卖票任务,并没有发挥多线程处理任务速度快的优势。下面我们看看 Runnable 接口实现。
实现 Runnable 接口实现
1 | package com.thread; |
测试程序
1 | package com.thread; |
运行结果
如此,便发挥出了多线程的优势。