用ReentrantLock和Condition实现生产者和消费者模式

Posted tangquanbin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用ReentrantLock和Condition实现生产者和消费者模式相关的知识,希望对你有一定的参考价值。

前面一篇文章《wait、notify应用场景(生产者-消费者模式)》是一种生产者消费者模式实现,今晚这是Lock方式实现,下面是源码:

生产者代码:

/**
 * 生产者
 *
 * @author tangquanbin
 * @date 2018/12/18 22:10
 */
public class Producer implements Runnable {
    /**
     * 产品容器
     */
    private List<Integer> container;
    private Lock lock;
    /**
     * 生产者条件
     */
    private Condition producerCondition;
    /**
     * 消费者条件
     */
    private Condition consumerCondition;

    public Producer(List<Integer> container, Lock lock, Condition producerCondition, Condition consumerCondition) {
        this.container = container;
        this.lock = lock;
        this.producerCondition = producerCondition;
        this.consumerCondition = consumerCondition;
    }

    public void produce() {
        //产品容器容量大小
        int capacity = 5;
        try {
            //获得锁
            lock.lock();
            //容器满了,不在生产
            if (container.size() == capacity) {
                System.out.println("生产满了。。。。");
                producerCondition.await();
            }
            Random random = new Random();
            int p = random.nextInt(50);
            //模拟1秒生产一个产品
            TimeUnit.MILLISECONDS.sleep(1000);
            System.out.println("生产产品:" + p);
            container.add(p);
            //生产一个产品,通知消费者
            consumerCondition.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //释放锁
            lock.unlock();
        }

    }

    @Override
    public void run() {
        while (true) {
            produce();
        }
    }
}

消费者代码:

/**
 * @author tangquanbin
 * @date 2018/12/18 22:16
 */
public class Consumer implements Runnable{
    /**
     * 产品容器
     */
    private List<Integer> container;
    private Lock lock;
    /**
     * 生产者条件
     */
    private Condition producerCondition;
    /**
     * 消费者条件
     */
    private Condition consumerCondition;

    public Consumer(List<Integer> container, Lock lock, Condition producerCondition, Condition consumerCondition) {
        this.container = container;
        this.lock = lock;
        this.producerCondition = producerCondition;
        this.consumerCondition = consumerCondition;
    }

    /**
     * 消费者消费产品
     */
    private void consume(){
        try {
            //获得锁
            lock.lock();
            //容器大小为null,不消费
            if (container.size() == 0) {
                System.out.println("消费完了。。。。");
                consumerCondition.await();
            }
            Integer p = container.remove(0);
            //模拟1秒消费一个产品
            TimeUnit.MILLISECONDS.sleep(1000);
            System.out.println("消费产品:" + p);
            //消费了,通知生产者
            producerCondition.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //释放锁
            lock.unlock();
        }
    }
    @Override
    public void run() {
        while (true){
           consume();
        }
    }
}

测试代码:

public class ProducerConsumerTest {
    public static void main(String[] args) {
        List<Integer> container = new ArrayList<>();
        Lock lock = new ReentrantLock();
        Condition producerCondition = lock.newCondition();
        Condition consumerCondition = lock.newCondition();
        Thread producer = new Thread(new Producer(container,lock,producerCondition,consumerCondition));
        Thread consumer = new Thread(new Consumer(container,lock,producerCondition,consumerCondition));
        producer.start();
        consumer.start();
    }
}

ReentrantLock 公平锁和非公平锁

非公平锁:获取锁的方式是抢占式的,随机的。默认ReentrantLock()是非公平的。jdk1.8源码如下:

public ReentrantLock() {
sync = new NonfairSync();
}


公平锁:线程获取锁的顺序是按照线程加锁的顺序来分配的。ReentrantLock(true)是公平的。jdk1.8源码如下:

public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}

  


以上是关于用ReentrantLock和Condition实现生产者和消费者模式的主要内容,如果未能解决你的问题,请参考以下文章

ReentrantLock 和 Condition的使用

用ReentrantLock和Condition实现线程间通信

Java多线程之ReentrantLock与Condition

Java ReEntrantLock 之 Condition条件(Java代码实战-002)

Condition的await-signal流程详解

ReentrantLock等待通知机制Condition介绍