Java Threads

</>Coding Tamilan.← Java course & curriculum
Java Masterclass · Lesson 48 / 50 · English

Java Threads

Separate a task from when it executes.

Step-by-step explanationsRunnable JavaPractice + answer

Read this topic in தமிழ் ↗.

By the end of this lesson, you can…

  • Explain the key idea behind Threads.
  • Read and run a complete example, then predict what changes.
  • Recognize the topic-specific mistake discussed below.
01 / The concept

Understand the idea

A thread can execute independently of the calling thread. start schedules a new thread; calling run directly is just a normal method call on the current thread. Use join when the caller must wait for completion. Real shared-state work also needs correct synchronization.

02 / Step by step

Explore the details

Java Threads

Threads allows a program to operate more efficiently by doing multiple things at the same time.

Threads can be used to perform complicated tasks in the background without interrupting the main program.

Creating a Thread

There are two ways to create a thread.

It can be created by extending the Thread class and overriding its run() method:

Another way to create a thread is to implement the Runnable interface:

Running Threads

If the class extends the Thread class, the thread can be run by creating an instance of the class and call its start() method:

If the class implements the Runnable interface, the thread can be run by passing an instance of the class to a Thread object's constructor and then calling the thread's start() method:

Differences between "extending" and "implementing" Threads The major difference is that when a class extends the Thread class, you cannot extend any other class, but by implementing the Runnable interface, it is possible to extend from another class as well, like: class MyClass extends OtherClass implements Runnable.

Concurrency Problems

Because threads run at the same time as other parts of the program, there is no way to know in which order the code will run. When the threads and main program are reading and writing the same variables, the values are unpredictable. The problems that result from this are called concurrency problems.

Three Ways to Create a Thread

Java reference fragmentJAVA
// Way 1 — Extend Thread class
class MyThread extends Thread {
    public void run() {
        System.out.println("Thread running: " + getName());
    }
}
new MyThread().start();

// Way 2 — Implement Runnable (preferred — allows extending other classes)
class MyTask implements Runnable {
    public void run() {
        System.out.println("Runnable running: " + Thread.currentThread().getName());
    }
}
new Thread(new MyTask()).start();

// Way 3 — Lambda (Java 8+, most concise)
new Thread(() -> System.out.println("Lambda thread!")).start();

Thread Lifecycle

StateDescriptionHow to reach it
NEWThread created but not yet startednew Thread(task)
RUNNABLEReady to run (waiting for CPU time)thread.start()
RUNNINGCurrently executing run()JVM scheduler selects it
BLOCKED/WAITINGPaused — waiting for lock or another threadsleep(), wait(), join()
TERMINATEDrun() method has finishedNormal completion or exception

start() vs run(): Always call start() — it creates a new thread and calls run() on it. Calling run() directly just executes the method on the current thread — no new thread is created.

To avoid concurrency problems, it is best to share as few attributes between threads as possible. If attributes need to be shared, one possible solution is to use the isAlive() method of the thread to check whether the thread has finished running before using any attributes that the thread can change.

03 / Read and predict

A complete runnable example

This complete Main.java program focuses on the lesson idea. Reference fragments above may demonstrate individual statements; this example includes the imports, entry point, and supporting types it needs.

Main.java · complete runnable exampleJAVA
public class Main {
    public static void main(String[] args) throws Exception {
        Thread worker = new Thread(() -> System.out.println("Worker finished"));
        worker.start();
        worker.join();
        System.out.println("Main continues");
    }
}
Predict first. Then reveal the expected output / வெளியீடு
Worker finished
Main continues

The output shown was checked by running this complete example. Trace the executed statements in order, then compare with your run.

04 / Learn by changing

Change it. Run it. Understand it.

Load this lesson example into the editor. Change one value or statement, predict the result, then press RUN to execute Java.

Open Java editor ↗
After the editor loads, choose Load this lesson example, then press RUN.

Powered by OneCompiler. Code you run is sent to OneCompiler for execution. For Scanner examples, supply input in the editor I/O panel; for file examples, files exist in its execution environment.

05 / Your turn

Make it your own

Practice challenge

Remove join and run several times. What output order is guaranteed?

Reveal the answer and reasoning / விடை

Without join, either line can appear first. One particular run does not establish a guaranteed order.

One mistake to avoid: Thread.sleep is not a reliable replacement for coordination such as join, locks, or higher-level concurrency utilities.

Your learning checkpoint

  • Explain the example without reading the output first.
  • Make the change requested in the practice task.
  • Describe why the result changed—or why compilation failed.

Ready to move on? Follow the next lesson in course order, or return to the curriculum to review a prerequisite.

Coding Tamilan · Understand the idea. Try the code. Build the habit.