Joining Threads in Java

Naveen AnamaneniUpdated · 4 min read

The join() method in Java makes the current thread wait until another thread finishes. If the main thread calls worker.join(), main pauses (in the WAITING state) until worker has completed its run() method. join is used to wait for results, to finish work in the right order, and to make sure all threads are done before the program continues. In this lesson, you will learn join, its timeout version, and how to wait for several threads.

Declaration

Declaration
public final void join() throws InterruptedException
public final void join(long millis) throws InterruptedException
public final boolean join(Duration duration) throws InterruptedException

The Duration version (Java 19) returns true if the thread finished in time.

Example: Waiting for a Result

Let's see an example where the main thread needs a value computed by a worker.

JoinResult.java▶ Try it
public class JoinResult {
    static long total;
 
    public static void main(String[] args) throws InterruptedException {
        Thread worker = new Thread(() -> {
            long sum = 0;
            for (int i = 1; i <= 1_000_000; i++) {
                sum += i;
            }
            total = sum;
        });
 
        worker.start();
        worker.join();
        System.out.println("Total from worker: " + total);
    }
}
Output
Total from worker: 500000500000

Explanation: Without join(), the main thread might print total before the worker had finished, and see 0. join() waits for the worker to end. It also guarantees that everything the worker wrote is visible to the main thread afterwards, so reading total is safe.

Example: Waiting for Many Threads, and Timeouts

JoinMany.java▶ Try it
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
 
public class JoinMany {
    static void work(long ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
 
    public static void main(String[] args) throws InterruptedException {
        List<Thread> threads = new ArrayList<>();
        for (String name : List.of("Navika", "Srihitha", "Advitha")) {
            Thread t = new Thread(() -> work(100), name);
            threads.add(t);
            t.start();
        }
        for (Thread t : threads) {
            t.join();
        }
        System.out.println("All " + threads.size() + " threads finished");
 
        Thread slow = new Thread(() -> work(2000));
        slow.start();
        boolean done = slow.join(Duration.ofMillis(200));
        System.out.println("Slow thread done within 200 ms? " + done);
        slow.interrupt();
        slow.join();
    }
}
Output
All 3 threads finished
Slow thread done within 200 ms? false

Explanation: All three workers are started first, then joined one by one; the total wait is only as long as the slowest one. For the slow thread, join(Duration) gives up after 200 milliseconds and returns false, so the program can decide what to do, here interrupting the thread and waiting for it to stop.

Common Mistakes

Calling join() right after each start() in a loop. The threads then run one after another.

Reading a worker's result without join(). You may see an old or default value.

Calling Thread.currentThread().join(). The thread waits for itself forever.

Interview Corner

What does the join() method do?

join() causes the calling thread to wait until the target thread terminates; join(millis) and join(Duration) wait at most the given time. It throws InterruptedException if the waiting thread is interrupted. A successful join also establishes a happens-before relationship, so all actions of the joined thread are visible to the thread that called join.

Practice

  1. Easy: Start two threads that each print their name after a pause, and print "Both done" only after joining both.
  2. Harder: Split the sum of 1 to 10,000,000 across four threads, store each partial sum in an array, join them, and add the parts.

Quick check: join()

4 questions
1What does worker.join() do?
2What state is a thread in while waiting in join()?
3What does join(Duration) return if the thread didn't finish in time?
4How should you start and join several threads?

Key Takeaways

Was this tutorial helpful?

Lesson 386 of 482