ReentrantLock 的条件变量 Condition 机制,轻松解锁多线程协作
2023-11-10 19:00:40
前言
在 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 来实现多线程协作。希望这篇文章对你有帮助。