本文目录导读:

- 使用
Thread.sleep()- 简单等待 - 使用
wait()和notify()- 生产者消费者模式 - 使用
CountDownLatch- 等待多个线程完成 - 使用
CyclicBarrier- 等待线程到达屏障 - 使用
CompletableFuture- 异步等待 - 模拟实际场景:多线程下载等待
- 选择建议
我来介绍几种常见的 Java 线程等待案例实现方式:
使用 Thread.sleep() - 简单等待
public class SleepWaitExample {
public static void main(String[] args) {
System.out.println("开始执行:" + System.currentTimeMillis());
try {
// 等待 2 秒
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("结束执行:" + System.currentTimeMillis());
}
}
使用 wait() 和 notify() - 生产者消费者模式
public class WaitNotifyExample {
private static final Object lock = new Object();
private static boolean ready = false;
public static void main(String[] args) {
// 等待线程
Thread waiter = new Thread(() -> {
synchronized (lock) {
while (!ready) {
try {
System.out.println("等待者:等待条件满足...");
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("等待者:条件满足,继续执行");
}
});
// 通知线程
Thread notifier = new Thread(() -> {
try {
Thread.sleep(2000); // 模拟一些工作
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock) {
ready = true;
lock.notify(); // 通知等待的线程
System.out.println("通知者:条件已设置,通知等待线程");
}
});
waiter.start();
notifier.start();
}
}
使用 CountDownLatch - 等待多个线程完成
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3);
// 创建 3 个工作线程
for (int i = 0; i < 3; i++) {
final int workerId = i;
new Thread(() -> {
try {
System.out.println("工作者 " + workerId + " 开始工作");
Thread.sleep((long) (Math.random() * 3000));
System.out.println("工作者 " + workerId + " 完成工作");
latch.countDown(); // 完成工作,计数器减1
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
System.out.println("主线程等待所有工作者完成...");
latch.await(); // 等待计数器变为0
System.out.println("所有工作者已完成,主线程继续执行");
}
}
使用 CyclicBarrier - 等待线程到达屏障
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
int partyCount = 3;
CyclicBarrier barrier = new CyclicBarrier(partyCount, () -> {
System.out.println("所有线程已到达屏障点,执行屏障动作");
});
// 创建 3 个线程
for (int i = 0; i < partyCount; i++) {
final int threadId = i;
new Thread(() -> {
try {
System.out.println("线程 " + threadId + " 执行第一阶段");
Thread.sleep((long) (Math.random() * 3000));
System.out.println("线程 " + threadId + " 到达屏障点");
barrier.await(); // 等待其他线程到达
System.out.println("线程 " + threadId + " 执行第二阶段");
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
使用 CompletableFuture - 异步等待
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 异步执行任务
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000);
return "任务结果";
} catch (InterruptedException e) {
return "任务被中断";
}
});
System.out.println("主线程继续执行其他操作...");
// 等待异步任务完成并获取结果
String result = future.get();
System.out.println("异步任务结果: " + result);
}
}
模拟实际场景:多线程下载等待
import java.util.concurrent.atomic.AtomicInteger;
public class DownloadWaitExample {
private static final AtomicInteger completedDownloads = new AtomicInteger(0);
private static final int TOTAL_FILES = 5;
public static void main(String[] args) {
Object lock = new Object();
// 模拟多个下载线程
for (int i = 0; i < TOTAL_FILES; i++) {
final int fileId = i;
new Thread(() -> {
try {
// 模拟下载过程
System.out.println("开始下载文件 " + fileId);
Thread.sleep((long) (Math.random() * 5000));
synchronized (lock) {
completedDownloads.incrementAndGet();
System.out.println("文件 " + fileId + " 下载完成 (已完成: "
+ completedDownloads.get() + "/" + TOTAL_FILES + ")");
if (completedDownloads.get() == TOTAL_FILES) {
lock.notifyAll(); // 所有文件下载完成
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
// 主线程等待所有下载完成
synchronized (lock) {
while (completedDownloads.get() < TOTAL_FILES) {
try {
System.out.println("主线程等待下载完成...");
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("所有文件下载完成,开始处理...");
}
}
选择建议
| 场景 | 推荐方案 |
|---|---|
| 简单延时 | Thread.sleep() |
| 线程间协作 | wait()/notify() |
| 等待一组线程完成 | CountDownLatch |
| 线程同步点 | CyclicBarrier |
| 异步任务等待结果 | CompletableFuture |
这些案例涵盖了 Java 中常见的线程等待场景,你可以根据实际需求选择合适的实现方式。