面试知识库
基础

线程间通信方式#

一句话答案#

Java 线程通信方式:volatile/synchronized(共享内存)、wait/notify、Lock/Condition、BlockingQueue、CompletableFuture。

核心要点

主要通信方式:

  1. volatile 变量:一个线程写,另一个线程读(可见性)
  2. synchronized + wait/notify:经典的等待-通知机制
  3. Lock + Condition:更灵活,支持多个等待队列
  4. BlockingQueue:生产者-消费者模式(推荐)
  5. CountDownLatch:一组线程等待另一组完成
  6. CyclicBarrier:一组线程互相等待到齐
  7. Semaphore:控制并发访问资源的线程数
  8. CompletableFuture:异步编排,线程间传递结果

常见场景选择:

场景推荐方式
生产者-消费者BlockingQueue
多线程协调CountDownLatch / CyclicBarrier
异步结果CompletableFuture
简单标志位volatile
面试回答(2分钟版)

Java 线程间通信方式可以从低级到高级分几个层次来理解。最基础的是通过共享变量通信,volatile 保证可见性,一个线程写另一个线程能立即读到最新值,适合简单的标志位场景。第二层是 synchronized 配合 wait 和 notify 的经典等待通知机制,wait 会释放锁并进入等待队列,notify 唤醒后重新竞争锁,但缺点是只有一个等待队列不够灵活。第三层是 Lock 配合 Condition,支持多个等待队列,可以精确唤醒特定条件上等待的线程。第四层是更高级的并发工具:BlockingQueue 是生产者消费者场景的首选,自动处理阻塞和唤醒;CountDownLatch 和 CyclicBarrier 用于多线程协调同步;CompletableFuture 用于异步编排和线程间传递结果。实际开发中推荐优先使用高层工具,避免直接操作底层的 wait 和 notify,因为高层工具封装了复杂的同步逻辑,不容易出错。

追问与易错

追问方向:

  • “生产者消费者最推荐用什么?”→ BlockingQueue,put/take 自动阻塞唤醒,不用手写 wait/notify,LinkedBlockingQueue 和 ArrayBlockingQueue 是最常用实现
  • “wait/notify 有什么缺陷?”→ 只有一个等待队列无法精确唤醒、必须在 synchronized 中使用、容易出现 lost wake-up 和虚假唤醒问题,编码复杂易出错
  • “CompletableFuture 和 Future 的区别?”→ Future.get() 阻塞等待且无法组合多个异步任务;CompletableFuture 支持非阻塞回调链(thenApply/thenCompose)、多任务组合(allOf/anyOf)和异常处理(exceptionally/handle)

易错点:

  • ❌ 用共享变量轮询代替 wait/notify——浪费 CPU
  • ❌ volatile 就能实现通信——只适合简单标志位