生产者消费者模式通过一个阻塞队列来解决两者之间的强耦合问题。阻塞队列相当于一个缓冲区,平衡消费者和生产者的处理能力。
阻塞队列有数据——生产者不生产,阻塞队列没数据——消费者不消费
一、synchronized+wait+notifyAll
生产
package com.ProductCusromer.method2; import java.util.List; import java.util.Random; /** * @author Millet * @date 2020/3/30 17:59 */ public class Product2 implements Runnable { private List list; public Product2(List list) { this.list = list; } //多个生产者对应多个消费者 @Override public void run() { Random random = new Random(50);//相当于商品 while (true){ synchronized (list){ while(list.size()>0){ //集合中有数据就停止写入,等待消费者消费完 try { list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } //执行到这说明集合没有数据了 list.add((random.nextInt(50))); //提示 System.out.println(Thread.currentThread().getName()+"线程生产了:"+ list.get(0)); list.notifyAll(); } } } }
消费者
package com.ProductCusromer.method2; import java.util.List; /** * @author Millet * @date 2020/3/30 18:07 */ public class Consumer2 implements Runnable { private List list; public Consumer2(List list) { this.list = list; } @Override public void run() { while(true){ synchronized (list){ while(list.size()<=0){//适合多生产者多消费者 try { list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } //提示 System.err.println(Thread.currentThread().getName()+"线程消费了:"+ list.remove(0)); list.notifyAll(); } } } }
二、ReetrantLock+Condition
生产者
package com.ProductCusromer.method3; import java.util.List; import java.util.Random; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; /** * @author Millet * @date 2020/3/30 17:59 */ public class Product3 implements Runnable { private List list; private Lock mLock; private Condition mCondition; public Product3(List list, Lock lock, Condition condition) { this.list = list; this.mLock = lock; this.mCondition = condition; } //一个生产者对应一个消费者 @Override public void run() { Random random = new Random(50);//相当于商品 while (true){ mLock.lock(); if(list.size()>0){ //集合中有数据就停止写入,等待消费者消费完 try { mCondition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } //执行到这说明集合没有数据了 list.add((random.nextInt(50))); //提示 System.out.println(Thread.currentThread().getName()+"线程生产了:"+ list.get(0)); mCondition.signalAll(); mLock.unlock(); } } }
消费者
package com.ProductCusromer.method2; import java.util.List; /** * @author Millet * @date 2020/3/30 18:07 */ public class Consumer2 implements Runnable { private List list; public Consumer2(List list) { this.list = list; } @Override public void run() { while(true){ synchronized (list){ while(list.size()<=0){//适合多生产者多消费者 try { list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } //提示 System.err.println(Thread.currentThread().getName()+"线程消费了:"+ list.remove(0)); list.notifyAll(); } } } }
三、BlockingQueue实现
生产者
package com.ProductCusromer.method3; import java.util.concurrent.BlockingQueue; /** * @author Millet * @date 2020/3/30 21:28 */ public class Product4 implements Runnable { private BlockingQueue queue; private String name; public Product4(String name, BlockingQueue queue) { this.queue = queue; this.name = name; } @Override public void run() { while(true){ try { int val = (int) Math.random(); queue.put(val); System.out.println(name + "生产:"+val+".当前队列长度:"+ queue.size()); } catch (InterruptedException e) { e.printStackTrace(); } } } }
消费者
package com.ProductCusromer.method3; import java.util.concurrent.BlockingDeque; import java.util.concurrent.BlockingQueue; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; /** * @author Millet * @date 2020/3/30 21:28 */ public class Consumer4 implements Runnable{ private BlockingQueue queue; private String name; public Consumer4(String name, BlockingQueue queue) { this.queue = queue; this.name = name; } @Override public void run() { try { while (true){ int val = (int) queue.take(); System.out.println(name + "消费:"+val+".当前队列长度:"+ queue.size()); } } catch (InterruptedException e) { e.printStackTrace(); } } }
测试
package com.ProductCusromer.method3; import com.ProductCusromer.method1.Consumer1; import com.ProductCusromer.method1.Product1; import javax.persistence.criteria.CriteriaBuilder; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @author Millet * @date 2020/3/30 20:33 */ public class Main { public static void main(String[] args) { BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(20); Product4 producer1 = new Product4("生产1号", queue); Product4 producer2 = new Product4("生产2号", queue); Product4 producer3 = new Product4("生产3号", queue); Consumer4 consumer1 = new Consumer4("消费1号", queue); Consumer4 consumer2 = new Consumer4("消费2号", queue); // 开始producer线程进行生产 new Thread(producer1).start(); new Thread(producer2).start(); new Thread(producer3).start(); // 开始consumer线程进行消费。 new Thread(consumer1).start(); new Thread(consumer2).start(); } }
结果