并发编程-Condition

Condition

一个Lock中应该绑定一个Condition对象。Condition是Java提供用来实现等待/通知的类。
我们知道Object对象提供了wait、waitAll、notify、notifyAll的方法用来实现线程的同步、等待和唤醒。
但Condition类提供了比wait/notify更丰富的功能,Condition对象由lock对象所创建的,同时一个Lock可以创建多个Condition对象,即创建多个对象监听器,这样就可以指定唤醒具体线程,而notify是随机唤醒线程。

Condition接口

  • void await():造成当前线程在接到信号或被中断之前一直处于等待状态。
  • boolean await(long time, TimeUnit unit):造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
  • long awaitNanos(long nanosTimeout):造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
  • void awaitUninterruptibly():造成当前线程在接到信号之前一直处于等待状态。
  • boolean awaitUntil(Date deadline):造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。
  • void signal():唤醒一个等待线程。

范例

public class Resource {
    private final int MAX_SIZE = 10;
    private List<Object> list = Lists.newArrayList();
    private Lock lock = new ReentrantLock();
    private Condition produceCondition = lock.newCondition();
    private Condition consumerCondition = lock.newCondition();

    public void produce() {
        while (true) {
            lock.lock();
            try {
                while (list.size() == MAX_SIZE) {
                    System.out.println("生产满了,暂时无法生产:" + list.size());
                    consumerCondition.signal();
                    try {
                        produceCondition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                list.add(new Object());
                System.out.println(Thread.currentThread().getName() + "生产新产品,共有:" + list.size());
            } finally {
                lock.unlock();
            }
        }
    }

    public void consume() {
        while (true) {
            lock.lock();
            try {
                while (CollectionUtils.isEmpty(list)) {
                    System.out.println("没有物品了,需要生产了");
                    produceCondition.signal();
                    try {
                        consumerCondition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() + "消费产品,共有:" + list.size());
                list.remove(0);
            } finally {
                lock.unlock();
            }
        }
    }

}

生产者线程

public class ProduceThread implements Runnable {

    private Resource resource;

    public ProduceThread(Resource resource){
        this.resource = resource;
    }

    @Override
    public void run() {
        resource.produce();
    }
}

消费者线程

public class ConsumerThread implements Runnable {

    private Resource resource;

    public ConsumerThread(Resource resource){
        this.resource = resource;
    }

    @Override
    public void run() {
        resource.consume();
    }
}

测试案例

public class ConditionDemo {
    public static void main(String[] args) throws InterruptedException {
        Resource resource = new Resource();
        ProduceThread produceThread = new ProduceThread(resource);
        ConsumerThread consumerThread = new ConsumerThread(resource);
        // 4个生产者
        for (int i = 0; i < 4; i++) {
            new Thread(produceThread).start();
            new Thread(consumerThread).start();
        }
    }
}
posted @ 2021-01-14 15:18  SpecialSpeculator  阅读(87)  评论(0编辑  收藏  举报