Java Programs›Multithreading›Create a Thread by Extending Thread

Create a Thread by Extending Thread in Java

intermediate·  Multithreading  ·  Concurrency

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.

Input
a worker that counts to 3
Output
Main starts the worker, the worker counts 1–3, main reports it finished

Java Program

Java
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

Main: starting worker Worker counting: 1 Worker counting: 2 Worker counting: 3 Main: worker finished

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.

How It Works
  1. 1Counter extends Thread and overrides run() with the counting loop.
  2. 2Main prints its first message before the worker exists, so that line always comes first.
  3. 3worker.start() launches the new thread, which calls run().
  4. 4worker.join() blocks main until the worker finishes, so the final message always comes last.
Because main does nothing but wait between 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

Threadrun()start()join()

Approach 2: start() vs run()

Java
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

run() is executing on: main run() is executing on: worker-1

Core Logic

Calling run() directly is just an ordinary method call on the current thread; only start() creates a new thread.

How It Works
  1. 1The thread is given the name worker-1 through the super(name) constructor.
  2. 2reporter.run() executes on the main thread and prints main.
  3. 3reporter.start() runs the same code on the new thread, which prints worker-1.
  4. 4join() waits for that thread before the program ends.
Same object, same method — the printed thread name proves only the second call ran concurrently.
💡

Key Point: Calling run() instead of start() is a classic interview trap: the code works, but nothing runs in parallel.

Key Concepts

Thread.currentThread()thread namesstart() vs run()

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.

Learn the Concept

Related Programs