并发控制-条件对象(Condition接口)

在并发控制的流程中,有一个很重要的概念,即为标题中的条件对象,条件对象对应的英文是Condition接口,我们使用ReentrantLock是,发现基于ReentrantLock可以获取到Contition接口,可以进行阻塞或者唤醒操作。本文从以下几个方面介绍。

Condition作用及用途

  Condition是基于ReentrantLock使用的,我们使用Condition可以实现条件判断

Condition代码演示

  演示代码1

    演示Condition的基本用法,如下代码所示:

    

package com.yang.concurrent;

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

/**
 * 本实例测试Condition的基本用法
 */
public class ConditionDemo1 {
    private ReentrantLock reentrantLock=new ReentrantLock();
    private Condition condition=reentrantLock.newCondition();

    public static void main(String[] args) {
        ConditionDemo1 conditionDemo1 = new ConditionDemo1();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    conditionDemo1.method2();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        conditionDemo1.method1();
    }

    public void method1(){
        reentrantLock.lock();
        try {
            System.out.println("条件不满足,等待中");
            condition.await();
            System.out.println("条件满足,可以运行");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            reentrantLock.unlock();
        }
    }

    public void method2(){
        reentrantLock.lock();
        try{
            condition.signal();
            System.out.println("条件转换为满足");
        }finally {
            reentrantLock.unlock();
        }
    }
}

    运行结果如下:

    

  演示代码2

    本代码演示用Condition实现生产者和消费者,如下实例代码所示

    

package com.yang.concurrent;

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

/**
 * 此实例我们用Condition去模拟生产者和消费者的实现
 */
public class ConditionDemo2 {
    private int queueSize = 10;
    private PriorityQueue<Integer> queue = new PriorityQueue<Integer>(10);
    private ReentrantLock reentrantLock = new ReentrantLock();
    private Condition notFull = reentrantLock.newCondition();
    private Condition notEmpty = reentrantLock.newCondition();

    public static void main(String[] args) {
        ConditionDemo2 conditionDemo2 = new ConditionDemo2();

        Provider provider = conditionDemo2.new Provider();
        Consumer consumer=conditionDemo2.new Consumer();
        provider.start();
        consumer.start();
    }

    class Provider extends Thread {
        @Override
        public void run() {
            provid();
        }

        private void provid() {
            while (true) {
                reentrantLock.lock();
                try {
                    //一直在生产
                    while (queue.size() == queueSize) {
                        try {
                            System.out.println("队列满了,等待中");
                            notFull.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    queue.offer(1);
                    notEmpty.signalAll();
                    System.out.println("对列中放入了一个数据,队列大小为:" + queue.size());

                } finally {
                    reentrantLock.unlock();
                }
            }
        }
    }

    class Consumer extends Thread {
        @Override
        public void run() {
            consume();
        }

        private void consume() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //一直在消费
            while (true) {


                reentrantLock.lock();
                try {

                    while (queue.size() == 0) {
                        //队列空
                        System.out.println("队列为空,等待中");
                        try {
                            notEmpty.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    queue.poll();
                    notFull.signalAll();
                    System.out.println("从队列中取走了一个数据,队列剩余:" + queue.size());
                } finally {
                    reentrantLock.unlock();
                }
            }
        }
    }

}

   运行结果如下图所示:

  

Condition使用说明

   当我们调用await方法后,就释放了锁

原文地址:https://www.cnblogs.com/cnxieyang/p/12774829.html