Java多线程通信核心机制详解

在Java中,多线程通信与协作主要通过以下几种核心机制实现,每种方式适用于不同的并发场景:


🔄 一、共享变量+同步控制(基础方式)

// 使用volatile保证可见性
private volatile boolean flag = false;

// 线程A
new Thread(() -> {
    while(!flag); // 等待标志位变化
    System.out.println("检测到标志位变化");
}).start();

// 线程B
new Thread(() -> {
    try { Thread.sleep(1000); } 
    catch (InterruptedException e) {}
    flag = true; // 修改共享状态
}).start();

特点

  • volatile 保证变量修改的可见性
  • ❌ 需配合synchronized保证原子性
  • ⚠️ 忙等待(while循环)消耗CPU资源

🤝 二、wait()/notify()机制(经典协作)

Object lock = new Object();

// 等待线程
new Thread(() -> {
    synchronized(lock) {
        try {
            lock.wait(); // 释放锁并等待
            System.out.println("被唤醒");
        } catch (InterruptedException e) {}
    }
}).start();

// 唤醒线程
new Thread(() -> {
    synchronized(lock) {
        lock.notify(); // 唤醒等待线程
    }
}).start();

关键点

  • ✅ 精确控制线程阻塞/唤醒
  • ❌ 必须配合synchronized使用
  • ⚠️ notify()随机唤醒单个线程,notifyAll()唤醒所有

📨 三、BlockingQueue(生产者-消费者模式)

BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);

// 生产者
new Thread(() -> {
    try {
        queue.put("数据"); // 阻塞式插入
    } catch (InterruptedException e) {}
}).start();

// 消费者
new Thread(() -> {
    try {
        String data = queue.take(); // 阻塞式获取
        System.out.println("消费:" + data);
    } catch (InterruptedException e) {}
}).start();

优势

  • ✅ 内置线程安全与阻塞控制
  • ✅ 支持容量限制(防止内存溢出)
  • 📊 常用实现:ArrayBlockingQueueLinkedBlockingQueue

🔐 四、CountDownLatch/CyclicBarrier(同步屏障)

CountDownLatch latch = new CountDownLatch(3);

// 工作线程
for (int i = 0; i < 3; i++) {
    new Thread(() -> {
        System.out.println("子线程完成");
        latch.countDown(); // 计数器减1
    }).start();
}

latch.await(); // 主线程等待计数器归零
System.out.println("所有线程执行完毕");

对比

工具特点重用性
CountDownLatch一次性使用,等待N个任务完成❌ 不可重用
CyclicBarrier可重复使用,线程互相等待✅ 可重用

✉️ 五、Exchanger(线程间数据交换)

Exchanger<String> exchanger = new Exchanger<>();

// 线程A
new Thread(() -> {
    try {
        String data = exchanger.exchange("数据A");
        System.out.println("收到:" + data);
    } catch (InterruptedException e) {}
}).start();

// 线程B
new Thread(() -> {
    try {
        String data = exchanger.exchange("数据B");
        System.out.println("收到:" + data);
    } catch (InterruptedException e) {}
}).start();

适用场景

  • ✅ 两个线程间双向数据交换
  • ❌ 不支持多线程组交换

🧠 六、Phaser(灵活阶段同步)

Phaser phaser = new Phaser(3); // 注册3个线程

for (int i = 0; i < 3; i++) {
    new Thread(() -> {
        System.out.println("阶段1完成");
        phaser.arriveAndAwaitAdvance(); // 等待所有线程
        
        System.out.println("阶段2完成");
        phaser.arriveAndDeregister(); // 退出注册
    }).start();
}

高级功能

  • ✅ 动态调整参与线程数
  • ✅ 支持多阶段同步控制

⚡ 最佳实践建议

  1. 优先选择高层工具
    使用BlockingQueueCountDownLatch等JDK并发工具,避免手动实现wait()/notify()
  2. 避免死锁
    按固定顺序获取多把锁,或使用tryLock()设置超时
  3. 虚拟线程优化(Java 21+)
    Thread.startVirtualThread(() -> { /* 任务代码 */ });
    
  4. 监控工具
    使用jstack或VisualVM分析线程阻塞状态

注意:跨线程通信时务必考虑可见性(volatile/happens-before原则)和原子性(锁/CAS),避免出现竞态条件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码的余温

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值