用Java写一个生产者-消费者队列
生产者消费者的模型作用
- 通过平衡生产者的生产能力和消费者的消费能力来提升整个系统的运行效率,这是生产者消费者模型最重要的作用。
- 解耦,这是生产者消费者模型附带的作用,解耦意味着生产者和消费者之间的联系少,联系越少越可以独自发展
使用阻塞队列来实现
package yunche.test.producer; import java.util.Random; import java.util.concurrent.BlockingQueue; /** * @ClassName: Producer * @Description: 生产者 * @author: yunche * @date: 2018/08/26 */ public class Producer implements Runnable { private final BlockingQueue<Integer> queue; public Producer(BlockingQueue q) { this.queue = q; } @Override public void run() { try { while(true) { //模拟耗时1s Thread.sleep(1000); queue.put(produce()); } } catch (InterruptedException e) { e.printStackTrace(); } } private int produce() { int n = new Random().nextInt(10000); System.out.println("Thread: " + Thread.currentThread().getName() + " produce: " + n); return n; } } package yunche.test.producer; import java.util.concurrent.BlockingQueue; /** * @ClassName: Consumer * @Description: 消费者 * @author: yunche * @date: 2018/08/26 */ public class Consumer implements Runnable { private final BlockingQueue<Integer> queue; public Consumer(BlockingQueue q) { this.queue = q; } @Override public void run() { while (true) { try { //模拟耗时 Thread.sleep(2000); consume(queue.take()); } catch (InterruptedException e) { e.printStackTrace(); } } } private void consume(Integer n) { System.out.println("Thread:" + Thread.currentThread().getName() + " consume: " + n); } } package yunche.test.producer; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; /** * @ClassName: Main * @Description: 测试类 * @author: yunche * @date: 2018/08/26 */ public class Main { public static void main(String[] args) { BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(100); Producer p = new Producer(queue); Consumer c1 = new Consumer(queue); Consumer c2 = new Consumer(queue); Thread producer = new Thread(p); producer.setName("生产者线程"); Thread consumer1 = new Thread(c1); consumer1.setName("消费者1"); Thread consumer2 = new Thread(c2); consumer2.setName("消费者2"); producer.start(); consumer1.start(); consumer2.start(); } }
使用wait-notify来实现
package yunche.test.producer; import java.util.LinkedList; import java.util.Random; /** * @ClassName: Producer * @Description: 生产者 * @author: yunche * @date: 2018/08/26 */ public class Producer implements Runnable { private final LinkedList<Integer> list; /** * 缓冲区大小 */ private final int maxSize; public Producer(LinkedList list, int size) { this.list = list; maxSize =size; } @Override public void run() { try { while(true) { //模拟耗时1s Thread.sleep(1000); synchronized (list) { if(list.size()==maxSize) { System.out.println("缓冲区已满,正在等待消费者消费..." + System.currentTimeMillis()); list.wait(); } else { list.add(produce()); list.notifyAll(); } } } } catch (InterruptedException e) { e.printStackTrace(); } } private int produce() { int n = new Random().nextInt(10000); System.out.println("Thread: " + Thread.currentThread().getName() + " produce: " + n); return n; } } package yunche.test.producer; import java.util.Date; import java.util.LinkedList; /** * @ClassName: Consumer * @Description: 消费者 * @author: yunche * @date: 2018/08/26 */ public class Consumer implements Runnable { private final LinkedList<Integer> list; public Consumer(LinkedList list) { this.list = list; } @Override public void run() { while (true) { try { synchronized(list) { //模拟耗时 Thread.sleep(1000); if(list.isEmpty()) { System.out.println("缓冲区已空,正在等待生产者生产..." + System.currentTimeMillis() + Thread.currentThread().getName()); list.wait(); } else { consume(list.poll()); list.notifyAll(); } } } catch (InterruptedException e) { e.printStackTrace(); } } } private void consume(Integer n) { System.out.println("Thread:" + Thread.currentThread().getName() + " consume: " + n); } } package yunche.test.producer; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; /** * @ClassName: Main * @Description: 测试类 * @author: yunche * @date: 2018/08/26 */ public class Main { public static void main(String[] args) { LinkedList<Integer> list = new LinkedList<>(); Producer p = new Producer(list, 10); Consumer c1 = new Consumer(list); Consumer c2 = new Consumer(list); Thread producer = new Thread(p); producer.setName("生产者线程"); Thread consumer1 = new Thread(c1); consumer1.setName("消费者1"); Thread consumer2 = new Thread(c2); consumer2.setName("消费者2"); producer.start(); consumer1.start(); consumer2.start(); } }
参考资料
不积跬步,无以至千里;不积小流,无以成江海
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!