Java Thread Communication Techniques: volatile, wait/notify, CountDownLatch, ReentrantLock with Condition, and LockSupport
This article demonstrates five Java thread‑communication approaches—using a volatile flag, Object.wait()/notify(), CountDownLatch, ReentrantLock with Condition, and LockSupport—each illustrated with complete code examples and explanations of their behavior and limitations.
The article presents a scenario where thread A adds the string "abc" to a list ten times and, after the fifth addition, thread B should be notified to perform its business logic. It then explores five different Java mechanisms to achieve this inter‑thread communication.
1. Using the volatile keyword – This method relies on shared memory; both threads monitor a volatile boolean flag that becomes true when the list reaches size five. The code shows thread B looping until the flag is set, while thread A updates the flag after the fifth insertion.
public class TestSync {
static volatile boolean notice = false;
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Thread threadA = new Thread(() -> {
for (int i = 1; i <= 10; i++) {
list.add("abc");
System.out.println("线程A添加元素,此时list的size为:" + list.size());
try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }
if (list.size() == 5) notice = true;
}
});
Thread threadB = new Thread(() -> {
while (true) {
if (notice) { System.out.println("线程B收到通知,开始执行自己的业务..."); break; }
}
});
threadB.start();
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
threadA.start();
}
}2. Using Object.wait() / Object.notify() – This classic approach requires a lock object and the synchronized block. Thread A calls notify() when the list size reaches five; thread B waits on the same lock until it is notified.
public class TestSync {
public static void main(String[] args) {
Object lock = new Object();
List<String> list = new ArrayList<>();
Thread threadA = new Thread(() -> {
synchronized (lock) {
for (int i = 1; i <= 10; i++) {
list.add("abc");
System.out.println("线程A添加元素,此时list的size为:" + list.size());
try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }
if (list.size() == 5) lock.notify();
}
}
});
Thread threadB = new Thread(() -> {
while (true) {
synchronized (lock) {
if (list.size() != 5) {
try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); }
}
System.out.println("线程B收到通知,开始执行自己的业务...");
}
}
});
threadB.start();
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
threadA.start();
}
}3. Using JUC CountDownLatch – Introduced in Java 5, this utility simplifies coordination. Thread A calls countDown() at the fifth insertion; thread B blocks on await() until the latch reaches zero.
public class TestSync {
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(1);
List<String> list = new ArrayList<>();
Thread threadA = new Thread(() -> {
for (int i = 1; i <= 10; i++) {
list.add("abc");
System.out.println("线程A添加元素,此时list的size为:" + list.size());
try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }
if (list.size() == 5) latch.countDown();
}
});
Thread threadB = new Thread(() -> {
while (true) {
if (list.size() != 5) {
try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); }
}
System.out.println("线程B收到通知,开始执行自己的业务...");
break;
}
});
threadB.start();
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
threadA.start();
}
}4. Using ReentrantLock with a Condition – This method mirrors wait/notify but uses explicit lock objects. Thread A signals the condition when the list reaches five; thread B awaits the condition before proceeding.
public class TestSync {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
List<String> list = new ArrayList<>();
Thread threadA = new Thread(() -> {
lock.lock();
for (int i = 1; i <= 10; i++) {
list.add("abc");
System.out.println("线程A添加元素,此时list的size为:" + list.size());
try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }
if (list.size() == 5) condition.signal();
}
lock.unlock();
});
Thread threadB = new Thread(() -> {
lock.lock();
if (list.size() != 5) {
try { condition.await(); } catch (InterruptedException e) { e.printStackTrace(); }
}
System.out.println("线程B收到通知,开始执行自己的业务...");
lock.unlock();
});
threadB.start();
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
threadA.start();
}
}5. Using LockSupport – This low‑level utility provides park/unpark methods that do not require a lock. Thread B parks until thread A unparks it after the fifth insertion.
public class TestSync {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
final Thread threadB = new Thread(() -> {
if (list.size() != 5) LockSupport.park();
System.out.println("线程B收到通知,开始执行自己的业务...");
});
Thread threadA = new Thread(() -> {
for (int i = 1; i <= 10; i++) {
list.add("abc");
System.out.println("线程A添加元素,此时list的size为:" + list.size());
try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }
if (list.size() == 5) LockSupport.unpark(threadB);
}
});
threadA.start();
threadB.start();
}
}The article concludes that while each method works, some (volatile, wait/notify, ReentrantLock) keep the notifying thread from releasing the lock immediately, whereas utilities like CountDownLatch and LockSupport offer clearer semantics. A final note advertises a WeChat public account for further Java resources.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architect's Guide
Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
