Using Java Thread Join: Synchronization of Threads
🧠 What Will You Learn in This Guide?
In this guide, you will learn how the Thread.join() method in Java works.
The goal is to control the order of execution by making one thread wait for the other to finish.
You will see the differences of the three different join() versions (parameterless, millis, millis+nanos) with the example code.
🧩 1. What is Thread.join()?
The Thread.join() method causes the current thread (e.g. main) to wait until a specific thread completes.
In this way, a sequential, synchronous and controlled working flow is achieved.
🔸 Types of join() Methods
| 💡 Method | 🧾 Description |
|---|---|
join() | It waits until the thread is completely finished. |
join(long millis) | It waits for the thread to finish or until the given time expires. |
join(long millis, int nanos) | Waits for the specified milliseconds + nanoseconds. |
💬 Note: If there is an interruption while waiting,
InterruptedExceptionwill be thrown.
⚙️ 2. Using join() Step by Step
The example below allows three threads to run sequentially and in a controlled manner.
package com.genixnode.threads;
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Thread başladı: " + Thread.currentThread().getName());
try {
Thread.sleep(4000); // Thread 4 saniye uyur
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread bitti: " + Thread.currentThread().getName());
}
}
public class ThreadJoinExample {
public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnable(), "tr1-islem");
Thread t2 = new Thread(new MyRunnable(), "tr2-islem");
Thread t3 = new Thread(new MyRunnable(), "tr3-islem");
t1.start();
// t1'in bitmesini 2 saniye bekle, ardından t2'yi başlat
try {
t1.join(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
// t1 tamamen bitmeden t3 başlamasın
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
t3.start();
// Ana thread, tüm işlemler bitene kadar bekler
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Tüm thread'ler tamamlandı, main thread sonlanıyor.");
}
}
➡️ This example shows the main thread ensuring orderly execution by waiting for others.
🧮 3. Sample Output
Thread başladı: tr1-islem
Thread başladı: tr2-islem
Thread bitti: tr1-islem
Thread başladı: tr3-islem
Thread bitti: tr2-islem
Thread bitti: tr3-islem
All threads are completed, the main thread is terminating. 📌 Here, tr3 does not start until tr1 is completed. In this way, threads run sequentially - synchronization is ensured.
⚡ 4. What You Need to Know When Using join()
| 💡 Status | 🧾 Description |
|---|---|
| Interruption Status | If another thread interrupts while waiting, InterruptedException occurs. |
| Timing Not Guaranteed | The duration of join(millis) depends on the operating system timer. |
| Infinite Wait | Without parameters join() waits until the thread finishes. |
| Efficiency | join Doesn't waste CPU cycles, just waits. |
| Alternatives | ExecutorService, Future.get() or CountDownLatch are more advanced solutions. |
❓ Frequently Asked Questions (FAQ)
- Does the join() method reduce performance?
No. join() does not put the thread to sleep; It just makes it wait (blocked state). CPU usage decreases and there is no waste of resources.
- Why doesn't join(long millis) wait for the full duration?
Thread timing is determined by the operating system. Java just passes the wait request.
- When does InterruptedException occur?
If the thread is interrupted by another thread (interrupt() is called) while waiting.
- How can I wait for multiple threads?
Call join() or use CountDownLatch for each individually.
- What's the difference in using join() instead of sleep()?
sleep() just saves time, while join() waits for the target thread to actually finish.
🎯 Result
In this guide, you learned how to use the Thread.join() method in Java to synchronize threads. Thread ordering is critical to get regular results, especially in parallel operations.
💬 You can test your multi-threaded applications on high-performance virtual servers on the GenixNode platform and experience the real-time synchronization difference.

