Create a Thread Using Runnable in Java
Problem
Runnable is a one-method interface describing a task; passing it to a Thread constructor separates what to do (the task) from how it runs (the thread).
Run a download task on a separate, named thread and report when it has finished.
Java Program
public class RunnableExample {
static class Downloader implements Runnable {
private final String file;
Downloader(String file) {
this.file = file;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " downloading " + file);
}
}
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Downloader("report.pdf"), "download-thread"); // task + name
t.start();
t.join();
System.out.println("Download task complete");
}
}Output
Core Logic
Implementing Runnable instead of extending Thread keeps the task an ordinary class that can carry its own data and still extend something else.
- 1
Downloader implements Runnablestores the file name and prints it insiderun(). - 2
new Thread(task, "download-thread")pairs the task with a thread and gives it a readable name. - 3
t.start()runs the task on that thread. - 4
t.join()waits for it before main prints the completion message.
Thread.currentThread().getName() inside the task prints download-thread, showing which thread did the work.Key Point: Prefer Runnable (or Callable) over extending Thread: Java has single inheritance, and the same task object can later be submitted to an ExecutorService unchanged.
Key Concepts
Approach 2: Runnable as a Lambda
public class RunnableLambda {
public static void main(String[] args) throws InterruptedException {
Runnable task = () -> System.out.println(Thread.currentThread().getName() + " says hello");
Thread t = new Thread(task, "lambda-thread");
t.start();
t.join();
System.out.println("Main thread: " + Thread.currentThread().getName());
}
}
Output
Core Logic
Because Runnable has a single abstract method, a lambda can supply the task without a separate class.
- 1
() -> System.out.println(...)is the whole task. - 2The lambda is passed to
new Thread(task, "lambda-thread"). - 3After
join(), main prints its own thread name for comparison.
lambda-thread, and the last line shows the main thread is called main.Key Point: Lambdas are ideal for short tasks; give longer tasks their own class so they can be tested and reused.
Key Concepts
Interview Questions
What's the difference between Runnable and Callable?
Runnable.run() returns nothing and can't throw checked exceptions. Callable.call() returns a value and may throw, and it's used with executors and Futures.
Why is implementing Runnable preferred over extending Thread?
It keeps the task separate from the thread, lets the class extend something else, and allows the same task to run in a thread pool.