java多线程发布订阅,多线程实现发布订阅升级版---遗留问题
昨天晚上遗留的两个问题
1.两个消费者消费消息都到100了,但是下图中的日志未打印出来
这个问题看代码
public classConsumerObjectOne implementsRunnable {
@Overridepublic voidrun() {
while(true) {
if(PudConThread.arrayBlockingQueue.size() > 0) {
if(PudConThread.hasConsumerTotal.get() >= PudConThread.total) {
System.out.println("消费者1--消费已达上限停止消费");return;}
/***获取最新的一条消息消费*/try{
//这个地方是关键
MessageVO messageVO = PudConThread.arrayBlockingQueue.take();System.out.println("消费者1消费消息"+ messageVO.toString());PudConThread.hasConsumerTotal.getAndAdd(1);} catch(InterruptedException e) {
e.printStackTrace();}
}
}
}
}
ArrayBlockingQueue 里面的take(),当队列里面的长度为空时,会进入await 状态,所以两个消费线程在消费掉最后一条时,队列是空队列,take()阻塞不能进行下次循环,消费结束消息不能打印
将消费线程中的,消费消息代码和判断消费消息数量代码位置对调一下就可以了
public classConsumerObjectOne implementsRunnable {
@Overridepublic voidrun() {
while(true) {
if(PudConThread.arrayBlockingQueue.size() > 0) {
/***获取最新的一条消息消费*/try{
MessageVO messageVO = PudConThread.arrayBlockingQueue.take();System.out.println("消费者1消费消息"+ messageVO.toString());PudConThread.hasConsumerTotal.getAndAdd(1);} catch(InterruptedException e) {
e.printStackTrace();}
if(PudConThread.hasConsumerTotal.get() >= PudConThread.total) {
System.out.println("消费者1--消费已达上限停止消费");return;}
}
}
}
}
在运行结果如下
不对调位置也可以如下改造,将take()换成poll()
public classConsumerObjectOne implementsRunnable {
@Overridepublic voidrun() {
while(true) {
if(PudConThread.hasConsumerTotal.get() >= PudConThread.total) {
System.out.println("消费者1--消费已达上限停止消费");return;}
if(PudConThread.arrayBlockingQueue.size() > 0) {
/***获取最新的一条消息消费*/MessageVO messageVO = PudConThread.arrayBlockingQueue.poll();if(messageVO != null) {
System.out.println("消费者1消费消息"+ messageVO.toString());PudConThread.hasConsumerTotal.getAndAdd(1);}
}
}
}
}
第2个问题 序号我们用的是AtomicInteger但是每次都会出现两个为0的序号
分析:每次出现两个为0的序号是,两个生产者在设置序号的时候用的是 AtomicInteger的 get() 方法这个只是返回当前最新值,所以两个生产者并发去get 获取到了初始值0
代码改造如下
public classProductObjectOne implementsRunnable {
@Overridepublic voidrun() {
while(true) {
if(PudConThread.hasProductTotal.get() >= PudConThread.total) {
System.out.println("产品已达上限,停止生产");return;}
MessageVO messageVO = newMessageVO(PudConThread.hasProductTotal.getAndAdd(1),UUID.randomUUID().toString(),"ProductObjectOne---this is pubsub test");try{
PudConThread.arrayBlockingQueue.put(messageVO);} catch(InterruptedException e) {
e.printStackTrace();}
}
}
}
运行结果如下,未出现重复的序号了
java多线程发布订阅,多线程实现发布订阅升级版---遗留问题相关推荐
- Redis 笔记(10)— 发布订阅模式(发布订阅单个信道、订阅信道后的返回值分类、发布订阅多个信道)
1. 发布-订阅概念 发布-订阅 模式包含两种角色,分别为发布者和订阅者. 订阅者可以订阅一个或者若干个频道(channel): 而发布者可以向指定的频道发送消息,所有订阅此频道的订阅者都可以收到此消 ...
- python redis订阅_python实现 redis订阅与发布
订阅者可以订阅一个或多个频道,发布者向一个频道发送消息后,所有订阅这个频道的订阅者都将收到消息,而发布者也将收到一个数值,这个数值是收到消息的订阅者的数量.订阅者只能收到自它开始订阅后发布者所发布的消 ...
- 调试笔记 — Redis 消息队列发布信息被消费者重复订阅多次牵扯到的 Tomcat 配置问题 [#00001]
最近在项目中发现了一个奇葩的 BUG ,当用户调用后台时,后台向消息队列中发布一条消息,这条消息会被监听器(消费者)监听到,有趣的事情就在这里,此时由于只发送了一条消息,照理说监听器应该只会触发一次, ...
- 微信个人订阅号如何发布多篇文章
大家好,今天我们来水一篇文章,很多小伙伴都不知道个人订阅号如何发布多篇文章的,发布一篇文章有时很鸡肋,今天我们一步步的进行更新! 一:登录微信公众平台mp.weixin.qq.com 二:点击首页的图 ...
- 文档订阅发布服务器,订阅服务器与发布服务器数据
订阅服务器与发布服务器数据 SQL Server 2005相对于SQL Server 2000来说,无论是性能还是功能都有一个相当大的提高,甚至可以用"革命"来形容这一次升级.SQ ...
- MQTT——EMQX学习笔记05——共享订阅、延迟发布
目录标题 一.共享订阅 (一)什么是共享订阅 (二)怎么实现共享订阅 (三)使用MQTTX客户端测试 (四)负载均衡策略 二.延迟发布 一.共享订阅 注意:共享订阅是在订阅时设置topic的名字,延迟 ...
- php redis消息订阅与发布_PHP使用Redis实现订阅发布与批量发送短信
原标题:PHP使用Redis实现订阅发布与批量发送短信 1 什么是redis订阅 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息.直接点, ...
- 多线程5:对象的发布与逸出(线程安全性)
发布:使对象能够在当前作用域之外的代码中使用 逸出:当某个不该被发布的对象被发布时,这种情况称为逸出 发布内部状态将会破坏封装性,并使得程序难以维持不变性条件 当某个对象逸出后,必须对程序进行分析,以 ...
- 订阅者java_RxJava:“java.lang.IllegalStateException:只允许一个订阅者!”
我正在使用RxJava来计算Android中某些传感器数据的标准化自动关联 . 奇怪的是,我的代码抛出一个异常("java.lang.IllegalStateException:只允许一个订 ...
- swingworker_使用SwingWorker的Java Swing中的多线程
swingworker 如果要使用Swing用Java编写桌面或Java Web Start程序,您可能会觉得需要通过创建自己的线程在后台运行某些程序. 没有什么可以阻止您在Swing中使用标准的 ...
最新文章
- 微软拼音输入法2007状态栏无法显示!
- js中的null和undefined总结
- MySQL中的索引(普通索引篇)
- 【编程题目】给你 10 分钟时间,根据上排给出十个数,在其下排填出对应的十个数...
- leetcode461. 汉明距离
- 搜狐视频怎么修改昵称
- springboot项目中jdk版本的问题
- mysql表名怎么拼接_自学MySQL第九天
- HTML5 canvas生成图片马赛克特效插件
- 用java程序写日历_用Java和C#写一个日历
- SQL 删除数据-select在当前表字段作为条件
- c++ string split_闲话Python之砍瓜切菜split()
- 住宅IP代理和数据中心IP代理有什么区别?
- YARN-ResourceManager重启
- 中医大2020年7月网考计算机应用基础,2020年7月网络教育统考《计算机应用基础》操作系统应用模拟题试卷2...
- 倾斜摄影 镜头畸变校准_什么是风景摄影的最佳镜头?
- 亚马逊、虾皮、来赞达、速卖通、ebay等跨境电商平台如何搭建一个稳定的自养号补单系统?
- 查询网站排名,收录情况
- Assets.xcassets:-1: Failed to find a suitable device for the type IBSimDeviceTypeiPad2x
- 链路跟踪Jaeger使用总结