本节内容主要是对 Java 锁机制之 Condition 接口进行讲解,Condition 接口是配合 Lock 接口使用的,我们已经学习过 Lock 接口的相关知识,那么接下来对 Condition 接口进行讲解。本节内容的知识点如下:
定义:Condition 接口也提供了类似 Object 的监视器方法,与 Lock 配合可以实现等待 / 通知模式。Condition 可以看做是 Obejct 类的 wait ()、notify ()、notifyAll () 方法的替代品,与 Lock 配合使用。
- public interface Condition {
- void await() throws InterruptedException;
- long awaitNanos(long nanosTimeout) throws InterruptedException;
- boolean await(long time, TimeUnit unit) throws InterruptedException;
- boolean awaitUntil(Date deadline) throws InterruptedException;
- void signal();
- void signalAll();
- }
等待机制方法简介:
通知机制方法简介:
Condition 对象是由 Lock 对象创建出来的 (Lock.newCondition),换句话说,Condition 是依赖 Lock 对象的。那么我们来看看如果创建 Condition 对象。
- Lock lock = new ReentrantLock();
- Condition condition1 = lock.newCondition();
- Condition condition2 = lock.newCondition();
场景修改:
以下是所有代码。
- public class DemoTest {
- public static void main(String[] args) {
- ProductFactory productFactory = new ProductFactory();
- new Thread(new Producer(productFactory),"1号生产者"). start();
- new Thread(new Producer(productFactory),"2号生产者"). start();
- new Thread(new Consumer(productFactory),"1号消费者"). start();
- new Thread(new Consumer(productFactory),"2号消费者"). start();
- new Thread(new Consumer(productFactory),"3号消费者"). start();
- }
- }
-
- class ProductFactory {
- private LinkedList
products; //根据需求定义库存,用 LinkedList 实现 - private int capacity = 10; // 根据需求:定义最大库存 10
- private Lock lock = new ReentrantLock(false);
- private Condition p = lock.newCondition();
- private Condition c = lock.newCondition();
- public ProductFactory() {
- products = new LinkedList
(); - }
- // 根据需求:produce 方法创建
- public void produce(String product) {
- try {
- lock.lock();
- while (capacity == products.size()) { //根据需求:如果达到 10 库存,停止生产
- try {
- System.out.println("警告:线程("+Thread.currentThread().getName() + ")准备生产产品,但产品池已满");
- p.await(); // 库存达到 10 ,生产线程进入 wait 状态
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- products.add(product); //如果没有到 10 库存,进行产品添加
- System.out.println("线程("+Thread.currentThread().getName() + ")生产了一件产品:" + product+";当前剩余商品"+products.size()+"个");
- c.signalAll(); //生产了产品,通知消费者线程从 wait 状态唤醒,进行消费
- } finally {
- lock.unlock();
- }
- }
-
- // 根据需求:consume 方法创建
- public String consume() {
- try {
- lock.lock();
- while (products.size()==0) { //根据需求:没有库存消费者进入wait状态
- try {
- System.out.println("警告:线程("+Thread.currentThread().getName() + ")准备消费产品,但当前没有产品");
- c.await(); //库存为 0 ,无法消费,进入 wait ,等待生产者线程唤醒
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- String product = products.remove(0) ; //如果有库存则消费,并移除消费掉的产品
- System.out.println("线程("+Thread.currentThread().getName() + ")消费了一件产品:" + product+";当前剩余商品"+products.size()+"个");
- p.signalAll();// 通知生产者继续生产
- return product;
- } finally {
- lock.unlock();
- }
- }
- }
-
- class Producer implements Runnable {
- private ProductFactory productFactory; //关联工厂类,调用 produce 方法
- public Producer(ProductFactory productFactory) {
- this.productFactory = productFactory;
- }
- public void run() {
- int i = 0 ; // 根据需求,对产品进行编号
- while (true) {
- productFactory.produce(String.valueOf(i)); //根据需求 ,调用 productFactory 的 produce 方法
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- i++;
- }
- }
- }
- class Consumer implements Runnable {
- private ProductFactory productFactory;
- public Consumer(ProductFactory productFactory) {
- this.productFactory = productFactory;
- }
- public void run() {
- while (true) {
- productFactory.consume();
- try {
- Thread.sleep(5000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
上述代码结果如下图所示