runnable + lambda 是最轻量的线程启动方式,只需一行代码 new thread(() -> { / do something / }).start() 即可;须调用 start() 而非 run(),且外部变量需为 final 或 effectively final;适合短小任务,耗时操作应改用 executorservice。

Runnable + Lambda 是最轻量的线程启动方式
不需要继承、不写新类、不重写整个 run() 方法——只要一行 Lambda 就能跑起来。Java 8+ 完全支持,new Thread(() -> { /* do something */ }).start() 就是全部。
别直接 new Thread() 后忘掉 start()
常见错误是写了 Lambda 却漏掉 start(),比如 new Thread(() -> System.out.println("hi")) 这个对象创建了但根本没运行;或者误调 run()(它只是普通方法调用,在当前线程同步执行,不启新线程)。
- ✅ 正确:
new Thread(() -> doWork()).start() - ❌ 错误:
new Thread(() -> doWork())(没 start) - ❌ 错误:
new Thread(() -> doWork()).run()(没走线程调度)
需要传参或捕获变量?注意 final 或 effectively final 限制
Lambda 内部访问外部变量时,Java 要求它们是 final 或“事实上的 final”(声明后未再赋值)。比如想把循环变量 i 带进线程里:
for (int i = 0; i System.out.println("Task " + capturedI)).start();
}
如果漏掉 capturedI,编译会报错:「local variables referenced from a lambda expression must be final or effectively final」。
简单任务够用,但别在 Lambda 里做耗时或阻塞操作
这种写法适合秒级、无状态、不依赖上下文的小任务,比如发个日志、触发个回调、轮询一次 HTTP 状态。一旦涉及 I/O、锁、长时间 sleep 或需要线程复用,就该换 ExecutorService 了——否则容易快速耗尽线程资源,而且无法控制并发数、异常传播也难捕获。
比如下面这段看着短,实际每调一次都新建线程,100 次就是 100 个线程:
for (int i = 0; i fetchFromApi()).start(); // 危险! }
真正上线的代码里,这个坑比语法错误更隐蔽。










