Runnable是Java中实现多线程的基础方式,避免单继承限制,强调任务与执行分离;可通过Lambda简化定义,须调用start()启动线程,更宜配合线程池使用以提升性能和可管理性。

在Java中使用Runnable接口是实现多线程最基础、最常用的方式之一。它不涉及继承,避免了单继承限制,适合任务逻辑与线程控制分离的场景。
为什么选择Runnable而不是Thread类
Runnable是一个函数式接口,只定义了一个run()方法,表示一个可被线程执行的任务。相比直接继承Thread类,它更轻量、更灵活:
- Java不支持多继承,若类已继承其他父类,就无法再继承
Thread -
Runnable强调“任务”概念,线程只是执行者,职责更清晰 - 便于与线程池(如
ExecutorService)配合使用
如何定义并启动Runnable任务
只需实现Runnable接口,重写run()方法,再将其传给Thread构造器即可启动:
示例:
立即学习“Java免费学习笔记(深入)”;
Runnable task = () -> {
System.out.println("任务开始执行,当前线程:" + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("任务执行完毕");
};
Thread thread = new Thread(task, "MyWorker");
thread.start(); // 注意:调用start(),不是run()
关键点:必须调用thread.start()来真正启动新线程;若误调task.run(),只是普通方法调用,仍在当前线程同步执行。
结合Lambda表达式简化写法
由于Runnable是函数式接口,可直接用Lambda表达式替代匿名内部类,代码更简洁:
- 传统匿名内部类写法冗长,易分散注意力
- Lambda让任务逻辑一目了然,尤其适合简单、短小的任务
- 仍需注意变量捕获限制:局部变量必须是effectively final(事实不变)
与线程池协同使用更推荐
手动创建Thread对象成本高、难管理,生产环境更推荐交给线程池调度:
ExecutorService pool = Executors.newFixedThreadPool(3);
pool.submit(() -> {
System.out.println("由线程池分配线程执行:" + Thread.currentThread().getName());
});
pool.shutdown(); // 使用完记得关闭
优势明显:复用线程、控制并发数、统一异常处理、支持异步结果(Future)等。










