Thread是线程实体类,负责生命周期管理;Runnable是任务接口,仅定义run()逻辑。Thread继承受限且难复用,Runnable支持多实现、易共享状态、适配线程池。

Java里Thread和Runnable的核心区别在于:一个是具体类,一个是任务接口;Thread负责线程的生命周期管理,Runnable只定义要执行的任务逻辑。
本质定位不同
Thread是Java中表示“线程实体”的类,它继承自Object并实现了Runnable接口,内部封装了线程启动、暂停、销毁等系统级能力。而Runnable是一个函数式接口,仅声明了一个无参无返回值的run()方法,纯粹描述“一段可被线程执行的代码”。
换句话说:Runnable定义“做什么”,Thread负责“怎么做”和“什么时候做”。
继承结构与扩展性差异
Java不支持多继承,如果一个类已继承了其他父类(比如Service或Activity),就无法再extends Thread;但可以随时implements Runnable,甚至同时实现多个接口。
立即学习“Java免费学习笔记(深入)”;
- 继承Thread → 占用唯一继承名额,耦合度高,复用性差
- 实现Runnable → 职责分离清晰,便于组合已有类,也天然适配线程池(ExecutorService只接受Runnable或Callable)
资源共享与对象复用
多个Thread实例可共享同一个Runnable对象,意味着它们执行的是同一份任务逻辑、操作同一组成员变量——这对模拟“多窗口卖同一场电影票”“多消费者处理同一队列”等场景非常关键。
而每个继承Thread的子类实例都独占一份run()逻辑副本,无法天然共享状态,需额外加锁或使用static变量,容易出错。
启动方式与底层机制
无论哪种方式,真正触发并发执行的都是Thread.start()。但两者的调用路径不同:
- 继承Thread:new MyThread().start() → JVM新建线程并直接执行MyThread.run()
- 实现Runnable:new Thread(new MyRunnable()).start() → JVM新建线程后,调用Thread.run(),其内部会检查target是否为空,不为空则执行target.run()
从源码看,Thread类内部持有一个private Runnable target字段,说明Runnable才是线程真正要跑的任务本体,Thread只是它的执行容器。










