跨线程通信的常见方法
在 Java 多线程开发中,实现跨线程通信主要通过以下几种方式:
wait/notify 机制 wait()
和 notify()
是 Object 类的方法,需在同步块或同步方法中使用。调用 wait()
的线程会释放锁并进入等待状态,直到其他线程调用 notify()
或 notifyAll()
唤醒它。
synchronized (lock) {
while (conditionNotMet) {
lock.wait();
}
// 执行操作
}
BlockingQueue BlockingQueue 是线程安全的队列,提供阻塞的 put 和 take 方法,适用于生产者-消费者模式。
BlockingQueue<String> queue = new LinkedBlockingQueue<>();
// 生产者
queue.put("data");
// 消费者
String data = queue.take();
CountDownLatch CountDownLatch 允许一个或多个线程等待其他线程完成操作。初始化时指定计数,调用 countDown()
减少计数,await()
阻塞直到计数为零。
CountDownLatch latch = new CountDownLatch(2);
// 线程1
latch.countDown();
// 线程2
latch.await();
高级通信工具
CyclicBarrier CyclicBarrier 让一组线程互相等待,到达屏障点时一起继续执行。与 CountDownLatch 不同,它可以重置重用。
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("All threads reached barrier");
});
// 线程调用
barrier.await();
Semaphore Semaphore 控制同时访问特定资源的线程数量,通过 acquire()
和 release()
管理许可。
Semaphore semaphore = new Semaphore(3);
semaphore.acquire();
try {
// 访问资源
} finally {
semaphore.release();
}
Exchanger Exchanger 用于两个线程间交换数据,调用 exchange()
方法会阻塞直到另一个线程也调用该方法。
Exchanger<String> exchanger = new Exchanger<>();
// 线程1
String data = exchanger.exchange("Data from Thread1");
// 线程2
String data = exchanger.exchange("Data from Thread2");
异步通信方式
Future 和 CompletableFuture Future 表示异步计算的结果,CompletableFuture 提供更丰富的异步编程功能,如链式调用和组合多个异步操作。
CompletableFuture.supplyAsync(() -> "Result")
.thenApply(s -> s + " processed")
.thenAccept(System.out::println);
Message Passing with Actors Akka 等框架提供 actor 模型,线程通过发送不可变消息通信,避免共享状态和锁竞争。
// Akka示例
actor.tell(new Message(), ActorRef.noSender());
选择合适的方法需根据具体场景:低延迟场景可能选择 wait/notify,复杂协调适合高级同步工具,高吞吐量系统可能用消息队列。