返回

ReentrantLock 的条件变量 Condition 机制,轻松解锁多线程协作

后端

前言

在 Java 并发编程中,我们经常需要处理多线程之间的协作。例如,当一个线程需要等待另一个线程执行完某个任务后才能继续执行时,我们就需要使用多线程协作机制来实现。

Java 中提供了两种常用的多线程协作机制:wait() 和 notify() 方法。wait() 方法可以让一个线程进入等待状态,直到被另一个线程唤醒。notify() 方法可以让一个线程唤醒另一个正在等待的线程。

wait() 和 notify() 方法的使用相对简单,但它们也有一个缺点:它们只能在同一个对象上使用。也就是说,如果两个线程需要协作,但它们不在同一个对象上,那么就无法使用 wait() 和 notify() 方法来实现协作。

为了解决这个问题,Java 提供了另一个多线程协作机制:Condition。Condition 是一个接口,它可以与 ReentrantLock 一起使用来实现多线程之间的协作。ReentrantLock 是一个可重入锁,它可以保证在同一个时刻只有一个线程能够访问共享资源。

Condition 的使用方式与 wait() 和 notify() 方法类似。首先,需要创建一个 Condition 对象,然后就可以使用 await() 方法让一个线程进入等待状态,直到被另一个线程唤醒。另一个线程可以使用 signal() 方法唤醒正在等待的线程。

Condition 的使用方式

Condition 的使用方式与 wait() 和 notify() 方法类似。首先,需要创建一个 Condition 对象,然后就可以使用 await() 方法让一个线程进入等待状态,直到被另一个线程唤醒。另一个线程可以使用 signal() 方法唤醒正在等待的线程。

// 创建一个 Condition 对象
Condition condition = lock.newCondition();

// 线程 1 进入等待状态
condition.await();

// 线程 2 唤醒正在等待的线程
condition.signal();

Condition 还提供了一个 signalAll() 方法,它可以唤醒所有正在等待的线程。

// 创建一个 Condition 对象
Condition condition = lock.newCondition();

// 线程 1 进入等待状态
condition.await();

// 线程 2 唤醒正在等待的线程
condition.signalAll();

使用 Condition 实现多线程协作

我们来看一个使用 Condition 来实现多线程协作的示例。在这个示例中,我们将使用两个线程来模拟生产者和消费者。生产者线程负责生产产品,消费者线程负责消费产品。

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ProducerConsumer {

    private static final ReentrantLock lock = new ReentrantLock();
    private static final Condition condition = lock.newCondition();

    private static int count = 0;

    public static void main(String[] args) {
        // 创建生产者线程
        Thread producer = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    // 获取锁
                    lock.lock();
                    try {
                        // 如果产品数量达到最大值,则等待
                        while (count == 10) {
                            condition.await();
                        }
                        // 生产一个产品
                        count++;
                        System.out.println("生产一个产品,当前产品数量:" + count);
                        // 通知消费者线程
                        condition.signal();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        // 释放锁
                        lock.unlock();
                    }
                }
            }
        });

        // 创建消费者线程
        Thread consumer = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    // 获取锁
                    lock.lock();
                    try {
                        // 如果产品数量为 0,则等待
                        while (count == 0) {
                            condition.await();
                        }
                        // 消费一个产品
                        count--;
                        System.out.println("消费一个产品,当前产品数量:" + count);
                        // 通知生产者线程
                        condition.signal();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        // 释放锁
                        lock.unlock();
                    }
                }
            }
        });

        // 启动生产者线程和消费者线程
        producer.start();
        consumer.start();
    }
}

在这个示例中,生产者线程和消费者线程都使用 Condition 来实现协作。当生产者线程生产出一个产品时,它会使用 signal() 方法唤醒消费者线程。当消费者线程消费了一个产品时,它会使用 signal() 方法唤醒生产者线程。

总结

Condition 是一个非常有用的多线程协作机制,它可以帮助你轻松实现多线程之间的协作。Condition 的使用方式与 wait() 和 notify() 方法类似,但它可以跨越不同的对象。

在本文中,我们介绍了 Condition 的使用方式,并通过一个示例来说明如何使用 Condition 来实现多线程协作。希望这篇文章对你有帮助。