Thread Methods in Java

In Java, threads are controlled and managed through a set of important methods provided by the Thread class. These methods define how threads are started, paused, coordinated, interrupted, and monitored.

Understanding these methods is crucial because they directly influence thread behavior, execution flow, and performance in concurrent applications.

In this article, we will explore the most commonly used thread methods: start(), run(), sleep(), yield(), join(), interrupt(), and isAlive().

start() vs run()

start()

The start() method is used to begin the execution of a thread. When you call start(), a new thread is created and the JVM internally calls the run() method.
        Thread t = new Thread(() -> {
            System.out.println("Thread executed using start()");
        });
        t.start();
Calling start() ensures that the task runs in a separate thread.

run()

The run() method contains the actual logic that the thread executes. However, calling run() directly does not create a new threadβ€”it simply runs like a normal method in the current thread.
        Thread t = new Thread(() -> {
            System.out.println("Inside run()");
        });
        t.run(); // NO new thread created 
Key Difference:
- start() β†’ creates a new thread
- run() β†’ executes in current thread

sleep() and yield()

sleep()

The sleep() method pauses the execution of the current thread for a specified duration. During this time, the thread enters the TIMED_WAITING state.
        try {
            Thread.sleep(2000); // sleep for 2 seconds 
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
Important Points:
- Does not release locks
- Throws InterruptedException
- Used for delays, retries, or simulation

yield()

The yield() method is a hint to the thread scheduler that the current thread is willing to pause and allow other threads of the same priority to execute.
Thread.yield(); 
Important Points:
- It is only a hint, not guaranteed
- The thread may continue execution immediately
- Rarely used in real-world applications

join() and interrupt()

join()

The join() method is used when one thread needs to wait for another thread to complete before continuing execution.
        Thread t = new Thread(() -> {
            System.out.println("Child thread running");
        });
        t.start();
        t.join(); // main thread waits here
        System.out.println("Main thread resumes"); 
Output
Child thread running
Main thread resumes
Key Points:
- Causes the current thread to enter WAITING or TIMED_WAITING
- Ensures sequential execution when required

interrupt()

The interrupt() method is used to signal a thread that it should stop what it is doing. It does not forcibly terminate the thread but sets an interrupt flag.
        Thread t = new Thread(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                System.out.println("Thread interrupted!");
            }
        });
        t.start();
        t.interrupt(); 
Output
Thread interrupted!
When t.start() is called, a new thread begins execution and enters the sleep state for 5 seconds using Thread.sleep(5000).

Immediately after starting the thread, t.interrupt() is invoked from the main thread. This sends an interrupt signal to the sleeping thread.

Since the thread is currently in a blocking state (sleep), the interrupt causes Thread.sleep() to throw an InterruptedException.
Key Points:
- Used for cooperative thread termination
- Interrupts blocking methods like sleep(), wait(), join()
- Best practice for stopping threads safely

isAlive()

The isAlive() method checks whether a thread is still running or not. It returns true if the thread has been started and has not yet terminated.

        Thread t = new Thread(() -> {
            System.out.println("Running...");
        });
        System.out.println(t.isAlive()); // false
        t.start();
        System.out.println(t.isAlive()); // true
Use Cases:
- Monitoring thread status
- Debugging concurrent applications
- Ensuring thread completion

Putting It All Together

The following example demonstrates multiple thread methods working together:
public class ThreadDemo {
    static void main(String[] args) throws Exception {
        Thread t = new Thread(() -> {
            try {
                System.out.println("Thread started");
                Thread.sleep(1000);
                System.out.println("Thread finished");
            } catch (InterruptedException e) {
                System.out.println("Interrupted!");
            }
        });
        t.start();
        System.out.println("Is alive: " + t.isAlive());
        t.join();
        System.out.println("Main thread resumes after join");
    }
}
Output
Thread started
Is alive: true
Thread finished
Main thread resumes after join
Thread methods provide fine-grained control over how threads behave and interact. Understanding the difference between start() and run(), the role of sleep() and yield(), and the coordination enabled by join() and interrupt() is essential for writing robust concurrent applications.

By mastering these methods, developers can build systems that are not only efficient but also predictable and safe in a multithreaded environment. In the next article, we will explore thread synchronization and how to manage shared resources effectively.
Nagesh Chauhan
Nagesh Chauhan
Principal Engineer | Java Β· Spring Boot Β· Python Β· Microservices Β· AI/ML

Principal Engineer with 14+ years of experience in designing scalable systems using Java, Spring Boot, and Python. Specialized in microservices architecture, system design, and machine learning.

Share this Article

πŸ’¬ Comments

Join the discussion