当前位置:首页 > Java

java如何实现线程间的通讯

2026-03-03 22:01:07Java

线程间通信的基本方法

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允许一个或多个线程等待其他线程完成操作。

java如何实现线程间的通讯

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允许两个线程在同步点交换数据。

java如何实现线程间的通讯

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();

使用管道流通信

PipedInputStreamPipedOutputStream实现线程间字节流通信。

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。选择时需考虑线程安全、性能需求和代码复杂度。

分享给朋友:

相关文章

vue如何实现到期提醒

vue如何实现到期提醒

实现 Vue 到期提醒功能 使用计算属性计算剩余时间 在 Vue 组件中定义一个计算属性,计算目标日期与当前日期的差值。通过 Date 对象获取时间戳并计算剩余天数或小时数。 computed: {…

vue手写签名如何实现

vue手写签名如何实现

实现手写签名的基本思路 在Vue中实现手写签名功能,通常需要借助HTML5的Canvas API来捕获用户的绘制操作。核心流程包括初始化画布、监听触摸/鼠标事件、记录轨迹以及生成签名图片。 安装依赖…

vue如何实现登录

vue如何实现登录

Vue 实现登录功能的方法 创建登录表单组件 在 Vue 项目中创建一个登录表单组件,通常命名为 Login.vue。表单包含用户名和密码输入框,以及提交按钮。 <template>…

vue如何实现原理

vue如何实现原理

Vue 实现原理的核心机制 Vue.js 的核心实现原理基于响应式系统、虚拟 DOM 和组件化设计。以下是关键机制的详细解析: 响应式系统 Vue 通过 Object.defineProperty(…

react如何实现混入

react如何实现混入

在React中实现混入(Mixin)功能可以通过以下几种方式实现,React官方已不推荐使用传统的React.createClass混入方式,但可通过高阶组件或自定义Hook替代。 高阶组件(HOC…

java如何实现跨平台

java如何实现跨平台

Java实现跨平台的原理 Java通过“一次编写,到处运行”的设计理念实现跨平台能力。其核心机制包括: Java虚拟机(JVM) Java源代码编译为字节码(.class文件),由JVM解释执行。不…