在 Java 中,多线程通信通常指的是多个线程之间协调工作、交换数据或控制执行顺序。常见方式如下(从常用到高级):
多个线程共享同一个变量,通过 volatile 保证可见性。
class Demo {
volatile boolean flag = false;
void threadA() {
flag = true; // 修改共享变量
}
void threadB() {
while (!flag) {
// 等待
}
System.out.println("收到通知");
}
}
✅ 优点:简单
❌ 缺点:轮询浪费 CPU,不能精确控制
必须在 synchronized 代码块中使用
class Demo {
final Object lock = new Object();
void consumer() throws InterruptedException {
synchronized (lock) {
lock.wait(); // 释放锁,等待
System.out.println("被唤醒");
}
}
void producer() {
synchronized (lock) {
lock.notify(); // 唤醒一个线程
}
}
}
✅ 适合线程间等待-通知 ❌ 容易死锁、写错位置
java.util.concurrent.locks
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
void consumer() throws InterruptedException {
lock.lock();
try {
condition.await();
System.out.println("被唤醒");
} finally {
lock.unlock();
}
}
void producer() {
lock.lock();
try {
condition.signal();
} finally {
lock.unlock();
}
}
✅ 可多条件
✅ 比 wait/notify 更清晰
线程安全队列,自动阻塞
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
// 生产者
queue.put(1);
// 消费者
int value = queue.take(); // 没有数据会阻塞
✅ 解耦生产者和消费者
✅ 不需要手动同步
CountDownLatch latch = new CountDownLatch(3);
// 子线程
latch.countDown();
// 主线程
latch.await(); // 等待
✅ 一次性
✅ 常用于初始化
CyclicBarrier barrier = new CyclicBarrier(3);
barrier.await(); // 等满 3 个线程
✅ 可重复使用
Semaphore semaphore = new Semaphore(2);
semaphore.acquire();
// 执行业务
semaphore.release();
Exchanger<String> exchanger = new Exchanger<>();
String data = exchanger.exchange("A");
✅ 用于线程间数据交换
Future<Integer> future = executor.submit(() -> 1 + 1);
Integer result = future.get();
或:
CompletableFuture.supplyAsync(() -> 1)
.thenAccept(System.out::println);
| 方式 | 场景 |
|---|---|
| volatile | 简单状态标志 |
| wait/notify | 基础等待通知 |
| Lock+Condition | 复杂同步 |
| BlockingQueue | 生产消费 |
| CountDownLatch | 等待完成 |
| CyclicBarrier | 多线程汇合 |
| Semaphore | 限流 |
| Future | 获取结果 |
如果你愿意,可以告诉我:
我可以给你更针对性的示例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。