java如何实现线程间的通讯
线程间通信的基本方法
Java中线程间通信主要通过共享内存和消息传递两种方式实现。共享内存涉及同步机制,消息传递则通过等待/通知机制或并发工具类完成。
使用wait()和notify()机制
通过Object类的wait()、notify()和notifyAll()方法实现经典的生产者-消费者模型。需在同步代码块或同步方法中调用这些方法。
class SharedResource {
private boolean isReady = false;
public synchronized void produce() {
while (isReady) {
wait(); // 等待消费
}
System.out.println("生产数据");
isReady = true;
notify(); // 通知消费者
}
public synchronized void consume() {
while (!isReady) {
wait(); // 等待生产
}
System.out.println("消费数据");
isReady = false;
notify(); // 通知生产者
}
}
使用BlockingQueue实现
java.util.concurrent.BlockingQueue提供线程安全的队列操作,支持阻塞插入和移除。
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);
// 生产者线程
new Thread(() -> {
try {
queue.put(1); // 阻塞插入
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
// 消费者线程
new Thread(() -> {
try {
Integer item = queue.take(); // 阻塞移除
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
使用CountDownLatch同步
CountDownLatch允许一个或多个线程等待其他线程完成操作。

CountDownLatch latch = new CountDownLatch(3);
// 工作线程
for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println("子线程执行");
latch.countDown();
}).start();
}
latch.await(); // 主线程等待
System.out.println("所有子线程完成");
使用CyclicBarrier协调
CyclicBarrier让一组线程相互等待,到达屏障点后继续执行。
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("所有线程到达屏障");
});
for (int i = 0; i < 3; i++) {
new Thread(() -> {
try {
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
使用Exchanger交换数据
Exchanger允许两个线程在同步点交换数据。

Exchanger<String> exchanger = new Exchanger<>();
new Thread(() -> {
try {
String data = exchanger.exchange("Thread1数据");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
new Thread(() -> {
try {
String data = exchanger.exchange("Thread2数据");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
使用管道流通信
PipedInputStream和PipedOutputStream实现线程间字节流通信。
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream(pis);
new Thread(() -> {
try {
pos.write("管道数据".getBytes());
pos.close();
} catch (IOException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
int data;
while ((data = pis.read()) != -1) {
System.out.print((char) data);
}
pis.close();
} catch (IOException e) {
e.printStackTrace();
}
}).start();
使用volatile变量
volatile关键字确保变量的可见性,但不保证原子性。
class SharedFlag {
volatile boolean flag = false;
}
SharedFlag shared = new SharedFlag();
new Thread(() -> {
while (!shared.flag) {
// 等待flag变化
}
System.out.println("检测到flag变化");
}).start();
new Thread(() -> {
try {
Thread.sleep(1000);
shared.flag = true;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
使用Condition接口
Condition接口提供更灵活的线程等待/通知机制,需与Lock配合使用。
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
new Thread(() -> {
lock.lock();
try {
condition.await(); // 等待
System.out.println("被唤醒");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}).start();
new Thread(() -> {
lock.lock();
try {
condition.signal(); // 唤醒
} finally {
lock.unlock();
}
}).start();
每种方法适用于不同场景:低级别控制可用wait()/notify(),生产者-消费者模型适合BlockingQueue,多阶段任务适合CyclicBarrier。选择时需考虑线程安全、性能需求和代码复杂度。






