700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 你说五毛就五毛? 生产者消费者模式(Producer Consumer Pattern)来讲解

你说五毛就五毛? 生产者消费者模式(Producer Consumer Pattern)来讲解

时间:2021-05-05 06:58:27

相关推荐

你说五毛就五毛? 生产者消费者模式(Producer Consumer Pattern)来讲解

目的

效率型设计模式, 意义在于不阻塞主流程的同时完成异步操作, 比如发邮件短信, 完成耗时的任务等

例子代码

最近蜂巢收费 5 毛的事件引起了业主和物业的强烈反对, 5 毛钱其实也不是很多, 掉地上有人都不看一眼的, 也就我们这种中年男人才会捡起来揣兜里, 我们先来看看没有蜂巢的时候我们的快递其实是比较不方便的, 我们假设快递物品必须要交到收货人手里, 不然可能会有丢失风险.

先定义一个货物类:

@Data@AllArgsConstructor//货物public class Good {private String name;}

比如我们定义一个消费者:

@Data@AllArgsConstructor//'消费者'public class Consumer {private String name;public void receiveGood(List<Good> goodList) {back2Home();System.out.println(name + "收到了" + goodList.toString());}//返回家中@SneakyThrowsprivate void back2Home() {Thread.sleep(1000);}}

定义一个快递小哥类:

@Data@AllArgsConstructor//快递员public class Courier {private String name;public void sendGood(Consumer consumer, List<Good> goodList) {consumer.receiveGood(goodList);}}

快递交个得等每个顾客回家才能给下一个人送快递:

StopWatch stopwatch = StopWatch.createStarted();final Map<Consumer, List<Good>> DELIVERY_INFO_MAP = new HashMap<>();DELIVERY_INFO_MAP.put(new Consumer("杰克马"), Arrays.asList(new Good("螃蟹"), new Good("河马")));DELIVERY_INFO_MAP.put(new Consumer("奶茶妹妹"), Arrays.asList(new Good("奶茶")));DELIVERY_INFO_MAP.put(new Consumer("小马哥"), Arrays.asList(new Good("肌肉")));Courier courier = new Courier("脸盲东");DELIVERY_INFO_MAP.forEach((k,v) -> {courier.sendGood(k,v);});stopwatch.stop();System.out.println("total time: " + stopwatch.getTime(TimeUnit.SECONDS));

输出:

杰克马收到了[Good(name=螃蟹), Good(name=河马)]奶茶妹妹收到了[Good(name=奶茶)]小马哥收到了[Good(name=肌肉)]total time: 3

问题分析

快递小哥得等每个 ‘消费者’ 回到家取快递, 太浪费时间了, 对顾客也不友好, 还得必须回到家取快递

丰巢模式(生产者消费者模式)

先定义一个消息(货物):

@Datapublic class EventItem<T> {private EventItemType eventType;private String eventId;private LocalDateTime eventDateTime;private T eventValue;}

先定义一个丰巢(消息队列):

public class ItemQueue {private BlockingQueue<EventItem> queue = new LinkedBlockingQueue<>(50);public void put(EventItem item) {try {queue.put(item);} catch (InterruptedException e) {throw new RuntimeException("put item to queue failed");}}public EventItem take() {try {return queue.take();} catch (InterruptedException e) {throw new RuntimeException("put item to queue failed");}}}

再定义一个生产者:

public class ItemProducer {private ItemQueue itemQueue;public ItemProducer(ItemQueue itemQueue) {this.itemQueue = itemQueue;}public <T> void generateEvent(EventItemType eventItemType, T value) {EventItem<T> eventItem = new EventItem<>();eventItem.setEventDateTime(LocalDateTime.now());eventItem.setEventId(UUID.randomUUID().toString());eventItem.setEventValue(value);eventItem.setEventType(eventItemType);itemQueue.put(eventItem);}}

再定义一个生产者:

public class ItemConsumer {private ItemQueue itemQueue;private EnumMap<EventItemType, ItemHander> typeItemHander;public ItemConsumer(ItemQueue itemQueue, EnumMap<EventItemType, ItemHander> typeItemHander) {this.itemQueue = itemQueue;this.typeItemHander = typeItemHander;}public void handleEvent() {EventItem eventItem = itemQueue.take();typeItemHander.get(eventItem.getEventType()).handle(eventItem);}}

针对不同消息的处理器接口:

public interface ItemHander<T> {void handle(EventItem<T> eventItem);}

本次的具体实现类, 本次放入消息的是货物:

@Data@AllArgsConstructorpublic class ConsumerItemHandler implements ItemHander<List<Good>> {private String name;@Overridepublic void handle(EventItem<List<Good>> eventItem) {System.out.println(name + "收到了" + eventItem.getEventValue().toString());}}

具体使用:

StopWatch stopwatch = StopWatch.createStarted();ItemQueue itemQueue = new ItemQueue();new ItemProducer(itemQueue).generateEvent(EventItemType.SEND_GOOD_TO_JIEKEMA, Arrays.asList(new Good("螃蟹"), new Good("河马")));new ItemProducer(itemQueue).generateEvent(EventItemType.SEND_GOOD_TO_NAICHA, Arrays.asList(new Good("奶茶")));new ItemProducer(itemQueue).generateEvent(EventItemType.SEND_GOOD_TO_XIAOMAGE, Arrays.asList(new Good("奶茶")));EnumMap<EventItemType, ItemHander> typeItemHander = new EnumMap<>(EventItemType.class);typeItemHander.put(EventItemType.SEND_GOOD_TO_JIEKEMA,new ConsumerItemHandler("杰克马"));typeItemHander.put(EventItemType.SEND_GOOD_TO_NAICHA,new ConsumerItemHandler("奶茶妹妹"));typeItemHander.put(EventItemType.SEND_GOOD_TO_XIAOMAGE,new ConsumerItemHandler("小马哥"));ItemConsumer itemConsumer = new ItemConsumer(itemQueue, typeItemHander);new Thread(() -> {while (true) {itemConsumer.handleEvent();}}).start();Thread.sleep(1000);stopwatch.stop();System.out.println("total time: " + stopwatch.getTime(TimeUnit.SECONDS));

输出:

杰克马收到了[Good(name=螃蟹), Good(name=河马)]奶茶妹妹收到了[Good(name=奶茶)]小马哥收到了[Good(name=奶茶)]total time: 1

类图如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fMBTmQZY-1602296002430)(/assets/04.png)]

课后作业

把消息队列换成持久存储的方式同时异步发送邮件和短信二种通知, 做一个邮件和短信的处理器

广告时间

最近也没人打赏了, 就我妈每次打赏二十元, 要放个广告了

字节跳动招聘:

java 开发社招:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QzhGWLBw-1602296002431)(/assets/00.png)]

/s/oFnSKT

前端开发社招:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9F9AZcbK-1602296002432)(/assets/01.png)]

/s/oFcxYL

实习生招聘:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-61NFAyeQ-1602296002433)(/assets/02.png)]

/s/oFqfKo

微信:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。