原创

第八篇 : Condition 线程通信


简介

  • Condition 接口描述了可能会与锁有关联的条件变量。这些变量在用 法上与使用 Object.wait 访问的隐式监视器类似,但提供了更强大的 功能。需要特别指出的是,单个 Lock 可能与多个 Condition 对象关 联。为了避免兼容性问题,Condition 方法的名称与对应的 Object 版 本中的不同。
  • 在 Condition 对象中,与 wait、notify 和 notifyAll 方法对应的分别是 awaitsignalsignalAll
  • Condition 实例实质上被绑定到一个锁上。要为特定 Lock 实例获得 Condition 实例,请使用其 newCondition() 方法。

一、实例

上一篇的讲解虚假唤醒的代码,现在我们synchronized 改为同步锁 Lock

package com.gf.demo;

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

public class TestProductorAndConsumer {

    public static void main(String args[]) {
        Clerk clerk = new Clerk();

        Productor pro = new Productor( clerk );
        Consumer cus = new Consumer( clerk );

        new Thread( pro, "生产者A" ).start();
        new Thread( cus, "消费者" ).start();

        new Thread( pro, "生产者C" ).start();
        new Thread( cus, "消费者D" ).start();

    }

}

/**
 * 店员
 */
class Clerk {
    private int product = 0;

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

    /**
     * 进货
     */
    public void get() {
        try {
            lock.lock();

            while (1 <= product) {
                System.out.println( "产品已满" );
                try {
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println( Thread.currentThread().getName() + " : " + ++product );
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 卖货
     */
    public void sale() {
        try {
            lock.lock();

            while (0 >= product) {
                System.out.println( "缺货 !" );
                try {
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println( Thread.currentThread().getName() + " : " + --product );
            condition.signalAll();

        } finally {
            lock.unlock();
        }
    }

}

/**
 * 生产者
 */
class Productor implements Runnable {

    private Clerk clerk;

    public Productor(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            try {
                //模拟网络延迟
                Thread.sleep( 200 );
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.get();
        }
    }
}

/**
 * 消费者
 */
class Consumer implements Runnable {

    private Clerk clerk;

    public Consumer(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            clerk.sale();
        }
    }
}
juc
  • 作者:程序员果果
  • 发表时间:2018-11-05 09:28
  • 版权声明:自由转载-非商用-非衍生-保持署名 (创意共享4.0许可证)
  • 公众号转载:请在文末添加作者公众号二维码
  • 评论