Create a Thread by Extending Thread in Java
Problem
A thread is an independent path of execution inside a program; subclassing java.lang.Thread and overriding run() defines what that path does.
Create a worker thread that counts from 1 to 3 while the main thread starts it and waits for it to finish.
Java Program
public class ExtendThreadExample {
static class Counter extends Thread {
@Override
public void run() { // the code the new thread executes
for (int i = 1; i <= 3; i++) {
System.out.println("Worker counting: " + i);
}
}
}
public static void main(String[] args) throws InterruptedException {
Counter worker = new Counter();
System.out.println("Main: starting worker");
worker.start(); // creates the new thread, which then calls run()
worker.join(); // main waits here until the worker is done
System.out.println("Main: worker finished");
}
}Output
Core Logic
The work lives in an overridden run(); calling start() asks the JVM to create a new thread that executes it, while join() keeps main from racing ahead.
- 1
Counter extends Threadand overridesrun()with the counting loop. - 2Main prints its first message before the worker exists, so that line always comes first.
- 3
worker.start()launches the new thread, which callsrun(). - 4
worker.join()blocks main until the worker finishes, so the final message always comes last.
start() and join(), the five lines always appear in the same order.Key Point: Without join(), "Main: worker finished" could print before the worker has counted at all — the order of two running threads isn't guaranteed.
Key Concepts
Approach 2: start() vs run()
public class StartVersusRun {
static class Reporter extends Thread {
Reporter(String name) {
super(name);
}
@Override
public void run() {
System.out.println("run() is executing on: " + Thread.currentThread().getName());
}
}
public static void main(String[] args) throws InterruptedException {
Reporter reporter = new Reporter("worker-1");
reporter.run(); // a plain method call: runs on the main thread
reporter.start(); // a real new thread named worker-1
reporter.join();
}
}
Output
Core Logic
Calling run() directly is just an ordinary method call on the current thread; only start() creates a new thread.
- 1The thread is given the name
worker-1through thesuper(name)constructor. - 2
reporter.run()executes on the main thread and printsmain. - 3
reporter.start()runs the same code on the new thread, which printsworker-1. - 4
join()waits for that thread before the program ends.
Key Point: Calling run() instead of start() is a classic interview trap: the code works, but nothing runs in parallel.
Key Concepts
Interview Questions
Can a thread be started twice?
No. Calling start() on a thread that has already been started throws IllegalThreadStateException. Create a new thread instead.
What's a daemon thread?
A background thread that doesn't keep the JVM alive. Call setDaemon(true) before start(); the JVM exits when only daemon threads remain.