本节内容主要是对 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; // 根据需求:定义最大库存 10private 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();}}}
}
上述代码结果如下图所示
