当前位置:首页 > Java

java线程如何同步和通讯

2026-03-17 19:12:06Java

Java线程同步与通信的方法

使用synchronized关键字

synchronized是Java中最基础的线程同步机制,可以修饰方法或代码块。当一个线程进入synchronized方法或代码块时,其他线程必须等待当前线程执行完毕才能进入。

public class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }
}

使用volatile关键字

volatile保证变量的可见性,即当一个线程修改了volatile变量的值,其他线程能立即看到最新值。但不保证原子性,适合单个变量的简单同步场景。

public class VolatileExample {
    private volatile boolean flag = false;
}

使用Lock接口

Java.util.concurrent.locks包提供了更灵活的锁机制,如ReentrantLock。相比synchronized,Lock提供了更多功能,如尝试获取锁、定时锁等待等。

Lock lock = new ReentrantLock();
public void method() {
    lock.lock();
    try {
        // 临界区代码
    } finally {
        lock.unlock();
    }
}

使用wait()/notify()机制

这是Java内置的线程间通信机制。wait()使线程等待并释放锁,notify()/notifyAll()唤醒等待的线程。必须在synchronized块中使用。

public synchronized void produce() throws InterruptedException {
    while (queue.isFull()) {
        wait();
    }
    // 生产数据
    notifyAll();
}

使用BlockingQueue

java.util.concurrent.BlockingQueue是线程安全的队列,提供了put()/take()等阻塞方法,天然适合生产者-消费者模式。

BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);
// 生产者
queue.put(item);
// 消费者
Integer item = queue.take();

使用CountDownLatch

CountDownLatch允许一个或多个线程等待其他线程完成操作。初始化时指定计数,countDown()减少计数,await()阻塞直到计数为0。

CountDownLatch latch = new CountDownLatch(3);
// 工作线程
latch.countDown();
// 主线程
latch.await();

使用CyclicBarrier

CyclicBarrier让一组线程互相等待,到达屏障点时才能继续执行。与CountDownLatch不同,它可以重置重用。

CyclicBarrier barrier = new CyclicBarrier(3, () -> {
    // 所有线程到达后执行
});
// 线程中
barrier.await();

使用Semaphore

Semaphore控制同时访问特定资源的线程数量,通过acquire()获取许可,release()释放许可。

Semaphore semaphore = new Semaphore(5);
semaphore.acquire();
try {
    // 访问资源
} finally {
    semaphore.release();
}

使用Exchanger

Exchanger允许两个线程在同步点交换数据,适用于校对工作等场景。

Exchanger<String> exchanger = new Exchanger<>();
// 线程1
String data2 = exchanger.exchange(data1);
// 线程2
String data1 = exchanger.exchange(data2);

使用Future和Callable

通过ExecutorService提交Callable任务,返回Future对象,可以获取异步计算结果。

java线程如何同步和通讯

ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(() -> {
    return 1 + 1;
});
Integer result = future.get();

选择合适的方法取决于具体场景:简单同步用synchronized,复杂锁需求用Lock,线程协作用wait/notify或并发集合,任务协调用CountDownLatch/CyclicBarrier,资源控制用Semaphore。

标签: 线程通讯
分享给朋友:

相关文章

vue实现父子通讯

vue实现父子通讯

父组件向子组件传值(Props) 在父组件中通过v-bind(或简写为:)向子组件传递数据。子组件通过props接收数据。 父组件代码示例: <template> <Chil…

php线程实现

php线程实现

在PHP中实现多线程可以通过多种方式,以下是常见的方法和示例: 使用pthreads扩展 pthreads是PHP的一个多线程扩展,适用于PHP 7.2及以上版本(Windows需ZTS版本)。…

js实现线程

js实现线程

JavaScript 是单线程语言,但可以通过以下方法模拟多线程或实现并发操作: Web Worker Web Worker 允许在后台运行脚本,与主线程并行执行。创建一个新的 Worker 线程:…

js实现线程池

js实现线程池

实现线程池的基本思路 JavaScript本身是单线程的,但可以通过Web Worker实现多线程。线程池的核心是管理多个Worker实例,避免频繁创建销毁的开销。 创建Worker管理类 cl…

js实现同步通讯

js实现同步通讯

同步通讯的实现方法 在JavaScript中,同步通讯通常指代码按照顺序执行,每一步操作完成后再进行下一步。以下是几种常见的同步通讯实现方法: 使用XMLHttpRequest同步请求 通过设置XM…

java如何让线程停止

java如何让线程停止

停止线程的方法 在Java中,线程的停止可以通过以下几种方式实现,每种方式有不同的适用场景和注意事项。 使用标志位控制线程退出 通过设置一个共享的volatile变量作为标志位,线程在运行时检查…