Creating Threads with Lambda Expressions
Fast recall
Quick revision
Core answer
Runnable is a functional interface, you can pass a lambda directly as the Runnable argument to the Thread constructor: new Thread(() -> doWork()).start(). This is the most concise way to create a thread for short inline tasks, and a method reference works too.Understanding that Runnable is a functional interface and awareness of modern Java syntax for concurrency.
Not realizing that any functional interface can be replaced with a lambda, thinking lambdas are only for Stream API operations.
Show all three syntaxes side-by-side: anonymous class, lambda, and method reference — explain when each is clearest.
Interview-ready guide
Interview answer
You can create a thread using a lambda expression because Runnable is a functional interface with exactly one abstract method.
Just pass a lambda directly to the Thread constructor. The lambda syntax is open paren close paren arrow, then your code.
For example, new Thread of a lambda that prints something, then dot start. The empty parentheses match the run method's no-argument signature. If it's a one-liner, you can skip the curly braces.
This is way more concise than the old anonymous inner class approach, where you had to write new Runnable with the whole override block. You can also use a method reference if you're just delegating to an existing method. The lambda can capture variables from the surrounding scope as long as they're effectively final, which means you can read them but not reassign them.
Use lambdas for short inline tasks like logging or sending notifications. If the logic is complex or more than ten lines, extract it to a proper Runnable class instead, because readability matters more than brevity. And in real applications, submit the lambda to an ExecutorService rather than creating raw threads.
Creating Threads with Lambda Expressions
Direct Answer
Because Runnable is a functional interface, you can pass a lambda directly as the Runnable argument to the Thread constructor: new Thread(() -> doWork()).start(). This is the most concise way to create a thread for short inline tasks, and a method reference works too.
Code Example
// Old style: anonymous inner class (verbose)
var thread1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Processing in " + Thread.currentThread().getName());
}
});
// Java 8: lambda expression (concise)
var thread2 = new Thread(() -> {
System.out.println("Processing in " + Thread.currentThread().getName());
});
// Java 8: one-liner lambda (for simple tasks)
var thread3 = new Thread(() -> System.out.println("Quick task"));
// Method reference (delegating to an existing method)
class OrderService {
void processOrder() {
System.out.println("Processing order");
}
}
var service = new OrderService();
var thread4 = new Thread(service::processOrder);
thread1.start();
thread2.start();
thread3.start();
thread4.start();
Common Mistakes & Pitfalls
- Capturing a mutable variable: A lambda can only capture effectively final locals. Trying to capture a changing loop counter is a compile error.
- Passing arguments to a method reference:
service::processOrder(123)is invalid — use() -> service.processOrder(123)instead. - Cramming logic into a lambda: A ten-plus-line lambda hurts readability. Extract it into a named
Runnableclass.
Check your understanding
Answer these without looking back at the article.
- Why can a Runnable be replaced by a lambda?
- What is an ExecutorService and why is it preferred over raw Thread creation?
- What is the difference between Runnable and Callable?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.