用ReentrantLock和Condition实现生产者和消费者模式
前面一篇文章《wait、notify应用场景(生产者-消费者模式)》是一种生产者消费者模式实现,今晚这是Lock方式实现,下面是源码:
生产者代码:
/** * 生产者 * * @author monkjaver * @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 monkjavaer * @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(); }