在多线程编程中,线程通信如同团队协作的密码——既要保证数据安全,又要实现高效协同。本文结合京东/字节/招行等大厂高频面试题,为你拆解Java线程通信的6大核心方案,从基础到进阶,彻底打通多线程任督二脉!
一、青铜段位:Object的"原始信号弹"
Java最原生的通信方式当属wait()/notify()组合拳,堪称线程通信的上古神器。
• 运作原理:通过synchronized锁配合对象监视器,wait()让线程挂起并释放锁,notify()唤醒等待队列中的线程
• 经典场景:实现生产者-消费者模型时,当库存满时生产者等待,空时消费者等待(参考网页2的商品库存案例)
• 致命缺陷:① 必须配合synchronized使用 ② notify随机唤醒可能"误伤"关键线程 ③ 无法实现定向唤醒
// 典型代码结构
synchronized(lock){
while(条件不满足){
lock.wait(); // 释放锁等待
}
// 处理业务
lock.notifyAll();
}
二、白银段位:Condition的"精准对讲机"
针对Object的缺陷,JUC包推出Condition接口,实现分区广播功能:
• 核心优势:① 支持多个等待队列(如独立的生产者/消费者等待区)② 支持超时等待 ③ 可中断的等待机制
• 实战技巧:在ReentrantLock中创建多个Condition,实现线程的定向唤醒(如网页1的案例中生产者只能唤醒消费者)
Lock lock = new ReentrantLock();
Condition produceCond = lock.newCondition();
Condition consumeCond = lock.newCondition();
// 堆代码 duidaima.com
// 生产者线程
lock.lock();
try{
while(库存满) produceCond.await();
// 生产逻辑
consumeCond.signal(); // 精准唤醒消费者
}finally{
lock.unlock();
}
三、黄金段位:LockSupport的"卫星电话"
当需要跨线程精准唤醒时,LockSupport.park()/unpark()展现了降维打击能力:
• 革命性突破:① 无需锁即可阻塞线程 ② 支持先唤醒后等待(许可证机制)③ 直接指定唤醒目标线程
• 典型应用:AQS同步器的底层实现、Netty的FastThreadLocal等高端框架
Thread worker = new Thread(()->{
LockSupport.park(); // 挂起
System.out.println("收到唤醒信号!");
});
LockSupport.unpark(worker); // 精准投放"许可证"
四、钻石段位:JUC三剑客
当需要处理复杂同步场景时,JUC工具类堪称并发编程瑞士军刀:
CountDownLatch:
• 类似"宇宙飞船发射倒计时",通过countDown()递减计数器,await()阻塞直到归零
• 适用场景:主线程等待所有子线程初始化完成
CyclicBarrier:
• "马拉松补给站"模式,所有线程到达屏障点才能继续执行
• 典型应用:多阶段任务处理(如网页4的三个运动员起跑案例)
Semaphore:
• "景区限流闸机",通过许可证控制并发流量
• 经典用法:数据库连接池资源管控
五、王者段位:BlockingQueue黑科技
对于生产者-消费者模型,BlockingQueue提供了零编码同步方案:
• 核心价值:内置锁和条件变量,自动处理线程阻塞/唤醒
• 性能王者:Disruptor框架的环形队列实现TPS可达百万级
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
// 生产者
queue.put(item); // 自动阻塞队列满时
// 消费者
queue.take(); // 自动阻塞队列空时
六、终极选择指南
场景
|
推荐方案
|
优势说明
|
简单同步
|
Object.wait/notify
|
兼容性好,JDK1.0支持
|
精准唤醒
|
Condition
|
多等待队列,避免惊群效应
|
线程控制权转移
|
LockSupport
|
无锁化设计,响应更快
|
资源限流
|
Semaphore
|
直观的许可证模型
|
批量任务协调
|
CountDownLatch
|
一次性协调多个线程
|
持续生产消费
|
BlockingQueue
|
开箱即用,性能优异
|
后记:在高并发场景下,线程通信如同精密钟表的齿轮咬合。理解每种方案的底层原理(如网页1分析的Condition与Object的演进关系),才能在不同业务场景中做出最优选择。记住:没有最好的方案,只有最合适的架构!