先回顾一下Thread类的部分知识:
空参构造方法
public Thread()
名字参数构造方法
public Thread(String name)
对象,名字参数构造方法
public Thread(Runnable target, String name)
静态方法currentThread()
public static Thread currentThread()返回对当前正在执行的线程对象的引用。
重写方法toString()
public String toString()返回对该线程的字符串表现形式:线程名,优先级,线程组名。
start()
public void start()使线程开始执行,JVM调用该线程的run方法。
现在来看一下最基本的两种实现方式:
实现方式一
实现方式二
两种方式的对比总结
| 特性 | 实现Runnable接口(第二种) | 继承Thread类(第一种) |
|---|---|---|
| 设计原则 | ✅ 符合"组合优于继承"原则 | ❌ 使用继承,限制了扩展性 |
| 代码耦合度 | ✅ 低耦合,线程任务与线程本身分离 | ❌ 高耦合,线程任务与线程绑定 |
| 资源共享 | ✅ 可以共享同一个Runnable对象 | ❌ 每个线程需要独立对象 |
| 扩展性 | ✅ 可以继承其他类 | ❌ 不能再继承其他类(Java单继承) |
| 内存开销 | ✅ 较小(可共享任务对象) | ❌ 较大(每个线程独立对象) |
| 代码结构 | ✅ 更清晰,职责分离 | ❌ 线程逻辑与任务逻辑混合 |
面向接口改善
注意到构造方法中的target参数类型是Myrunnable接口,意味着当我们创建许多的Runnable接口实现类来实现不同的任务,都可以将他们的实例对象作为参数传入进去。如下图
面向接口
当参数是接口时,我们可以传入实现该接口的任何对象。
构造时的改善
当我们为多个线程命名时,要用Thread类中的setName方法 一个一个命名,这时可以用到回顾中提到的构造方法。