Software Development

Java Thread Methods: A Comprehensive Guide


Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Java programming tutorial

Java Threads allow multiple tasks to run concurrently within a single program. This programming tutorial explores various methods for managing threads in Java. In particular, we will review methods that deal with thread states and properties, as well as their synchronization and interruption. In a later part we will cover methods for controlling thread priority, daemon threads, sleeping and waiting, as well as a couple of miscellaneous methods that do not fall into any of the aforementioned categories.

How to Start a Thread in Java

start()

The start() method initiates the execution of a thread. It calls the run() method defined in your thread class or runnable object. Invoking run() directly will not start a new thread, so it is crucial to use start(). Here is a code example showing its use:

public class Main {
    public static void main(String[] args) {
        Thread myThread = new Thread(new MyRunnable());
        myThread.start();
    }
}
      

run()

The run() method contains the code that will be executed in the thread. It must be overridden when extending the Thread class or implementing the Runnable interface.


class MyRunnable implements Runnable {
    public void run() {
        System.out.println("This is a runnable.");
    }
}
        

Thread States and Properties

getState()

The getState() method returns the current state of the thread as an integer. The possible states are:

  • NEW: The thread has been created but has not started yet.
  • RUNNABLE: The thread is actively executing or is ready to execute.
  • BLOCKED: The thread is blocked, waiting for a monitor lock.
  • WAITING: The thread is waiting indefinitely for another thread to perform a specific action.
  • TIMED_WAITING: The thread is waiting for a specified time period.
  • TERMINATED: The thread has completed its execution and terminated.

Here is some example code illustrating the above thread states:

Thread myThread = new Thread(() -> {
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
});

System.out.println(myThread.getState()); // Output: NEW

myThread.start();
System.out.println(myThread.getState()); // Output: RUNNABLE

try {
    myThread.join();
} catch (InterruptedException e) {
    e.printStackTrace();
}

System.out.println(myThread.getState()); // Output: TERMINATED

In this example, we created a thread (myThread), started it, and then checked its state at different points in its lifecycle.

isAlive()

The isAlive() method checks whether the thread is alive. A thread is considered alive if it has been started and has not yet completed. It returns true if the thread is alive, and false otherwise.

In the following code example, we create a new thread (myThread) but have not started it yet. We then check if the thread is alive using the isAlive() method, which will return false. After starting the thread, we check again, and this time it will return true:

Thread myThread = new Thread();
System.out.println(myThread.isAlive()); // Output: false
myThread.start();
System.out.println(myThread.isAlive()); // Output: true

getName()

The getName() method returns the name of the thread.

In this Java code example, we create a new thread (myThread) without specifying a name. The getName() method is used to retrieve and print the default name of the thread, which will be something like Thread-0:

Thread myThread = new Thread();
System.out.println(myThread.getName()); // Output: Thread-0

setName()

The setName() method sets the name of the thread.

In the next example code, we create a new thread (myThread) and then use setName() to set a custom name for the thread. We then use getName() again to retrieve and print the custom name:

Thread myThread = new Thread();
myThread.setName("CustomThread");
System.out.println(myThread.getName()); // Output: CustomThread

getId()

The getID() method returns the unique identifier for the thread.

In this example, we create a new thread (myThread) and then use getId() to retrieve and print the unique identifier assigned to the thread. The value will be platform-dependent:

Thread myThread = new Thread();
System.out.println(myThread.getId()); // Output: A unique identifier (platform-dependent)

getState()

The getState() method returns the current state of the thread as an enum value, which provides a more human-readable representation compared to the integer values returned by getState().

In the code example below, we create a new thread (myThread) and then use getState() to retrieve and print the current state of the thread. We also demonstrate how to get the name of the state using name(), which will be NEW in this case:

Thread myThread = new Thread();
System.out.println(myThread.getState()); // Output: NEW
System.out.println(myThread.getState().name()); // Output: NEW

Thread Synchronization and Interruption in Java

join()

The join() method allows one thread to wait for the completion of another. This can be useful when you need to ensure certain tasks are finished before moving on.

In the following code example, we have two threads (thread1 and thread2) that count from 1 to 5 with a delay of 1 second between each count. The main thread starts both of these threads:

public class JoinExample {

    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            for (int i = 1; i <= 5; i++) {
                System.out.println("Thread 1: Count " + i);
                try {
                    Thread.sleep(1000); // Simulating some work
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 1; i <= 5; i++) {
                System.out.println("Thread 2: Count " + i);
                try {
                    Thread.sleep(1000); // Simulating some work
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        thread1.start();
        thread2.start();

        try {
            thread1.join(); // Main thread waits for thread1 to finish
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Thread 1 has completed.");
    }
}

interrupt()

Java’s interrupt() method interrupts the thread, causing it to throw an InterruptedException the next time it checks for interrupts.

In this example, we create a thread (myThread) that counts from 1 to 5 with a delay of 1 second between each count. Inside the thread, we have a try-catch block to handle InterruptedException:

public class InterruptExample {

    public static void main(String[] args) {
        Thread myThread = new Thread(() -> {
            try {
                for (int i = 1; i <= 5; i++) {
                    System.out.println("Count: " + i);
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                System.out.println("Thread interrupted.");
            }
        });

        myThread.start();

        try {
            Thread.sleep(3000); // Main thread sleeps for 3 seconds
            myThread.interrupt(); // This will interrupt myThread
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

isInterrupted()

The isInterrupted() method Checks whether the thread has been interrupted. Unlike interrupt(), this does not clear the interrupted flag.

In our next code example, we create a thread (myThread) that counts from 1 to 5 with a delay of 1 second between each count. Inside the thread, we have a try-catch block to handle InterruptedException:

public class IsInterruptedExample {

    public static void main(String[] args) {
        Thread myThread = new Thread(() -> {
            try {
                for (int i = 1; i <= 5; i++) {
                    System.out.println("Count: " + i);
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                System.out.println("Thread interrupted.");
            }
        });

        myThread.start();

        try {
            Thread.sleep(3000); // Main thread sleeps for 3 seconds
            myThread.interrupt(); // This will interrupt myThread
            boolean interruptedStatus = myThread.isInterrupted(); // Check if interrupted
            System.out.println("Thread interrupted status: " + interruptedStatus);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

There is also a static version of isInterrupted(). The Thread.interrupted() method checks whether the current thread has been interrupted and clears the interrupted flag.

Final Thoughts on Java Thread Methods

This programming tutorial explored Java Thread methods that deal with thread states and properties, as well as their synchronization and interruption. The next part will cover methods for controlling thread priority, daemon threads, sleeping and waiting, along with some miscellaneous methods.