昨天晚上遗留的两个问题

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多线程发布订阅,多线程实现发布订阅升级版---遗留问题相关推荐

  1. Redis 笔记(10)— 发布订阅模式(发布订阅单个信道、订阅信道后的返回值分类、发布订阅多个信道)

    1. 发布-订阅概念 发布-订阅 模式包含两种角色,分别为发布者和订阅者. 订阅者可以订阅一个或者若干个频道(channel): 而发布者可以向指定的频道发送消息,所有订阅此频道的订阅者都可以收到此消 ...

  2. python redis订阅_python实现 redis订阅与发布

    订阅者可以订阅一个或多个频道,发布者向一个频道发送消息后,所有订阅这个频道的订阅者都将收到消息,而发布者也将收到一个数值,这个数值是收到消息的订阅者的数量.订阅者只能收到自它开始订阅后发布者所发布的消 ...

  3. 调试笔记 — Redis 消息队列发布信息被消费者重复订阅多次牵扯到的 Tomcat 配置问题 [#00001]

    最近在项目中发现了一个奇葩的 BUG ,当用户调用后台时,后台向消息队列中发布一条消息,这条消息会被监听器(消费者)监听到,有趣的事情就在这里,此时由于只发送了一条消息,照理说监听器应该只会触发一次, ...

  4. 微信个人订阅号如何发布多篇文章

    大家好,今天我们来水一篇文章,很多小伙伴都不知道个人订阅号如何发布多篇文章的,发布一篇文章有时很鸡肋,今天我们一步步的进行更新! 一:登录微信公众平台mp.weixin.qq.com 二:点击首页的图 ...

  5. 文档订阅发布服务器,订阅服务器与发布服务器数据

    订阅服务器与发布服务器数据 SQL Server 2005相对于SQL Server 2000来说,无论是性能还是功能都有一个相当大的提高,甚至可以用"革命"来形容这一次升级.SQ ...

  6. MQTT——EMQX学习笔记05——共享订阅、延迟发布

    目录标题 一.共享订阅 (一)什么是共享订阅 (二)怎么实现共享订阅 (三)使用MQTTX客户端测试 (四)负载均衡策略 二.延迟发布 一.共享订阅 注意:共享订阅是在订阅时设置topic的名字,延迟 ...

  7. php redis消息订阅与发布_PHP使用Redis实现订阅发布与批量发送短信

    原标题:PHP使用Redis实现订阅发布与批量发送短信 1 什么是redis订阅 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息.直接点, ...

  8. 多线程5:对象的发布与逸出(线程安全性)

    发布:使对象能够在当前作用域之外的代码中使用 逸出:当某个不该被发布的对象被发布时,这种情况称为逸出 发布内部状态将会破坏封装性,并使得程序难以维持不变性条件 当某个对象逸出后,必须对程序进行分析,以 ...

  9. 订阅者java_RxJava:“java.lang.IllegalStateException:只允许一个订阅者!”

    我正在使用RxJava来计算Android中某些传感器数据的标准化自动关联 . 奇怪的是,我的代码抛出一个异常("java.lang.IllegalStateException:只允许一个订 ...

  10. swingworker_使用SwingWorker的Java Swing中的多线程

    swingworker 如果要使用Swing用J​​ava编写桌面或Java Web Start程序,您可能会觉得需要通过创建自己的线程在后台运行某些程序. 没有什么可以阻止您在Swing中使用标准的 ...

最新文章

  1. 微软拼音输入法2007状态栏无法显示!
  2. js中的null和undefined总结
  3. MySQL中的索引(普通索引篇)
  4. 【编程题目】给你 10 分钟时间,根据上排给出十个数,在其下排填出对应的十个数...
  5. leetcode461. 汉明距离
  6. 搜狐视频怎么修改昵称
  7. springboot项目中jdk版本的问题
  8. mysql表名怎么拼接_自学MySQL第九天
  9. HTML5 canvas生成图片马赛克特效插件
  10. 用java程序写日历_用Java和C#写一个日历
  11. SQL 删除数据-select在当前表字段作为条件
  12. c++ string split_闲话Python之砍瓜切菜split()
  13. 住宅IP代理和数据中心IP代理有什么区别?
  14. YARN-ResourceManager重启
  15. 中医大2020年7月网考计算机应用基础,2020年7月网络教育统考《计算机应用基础》操作系统应用模拟题试卷2...
  16. 倾斜摄影 镜头畸变校准_什么是风景摄影的最佳镜头?
  17. 亚马逊、虾皮、来赞达、速卖通、ebay等跨境电商平台如何搭建一个稳定的自养号补单系统?
  18. 查询网站排名,收录情况
  19. Assets.xcassets:-1: Failed to find a suitable device for the type IBSimDeviceTypeiPad2x
  20. 链路跟踪Jaeger使用总结

热门文章

  1. Win7系统分区(C盘)扩容的一种可行的解决方案
  2. 关于不能远程连接Linux中Mysql数据库的问题
  3. 10分钟完成一个业务流程的发布
  4. 更改数据库对象所有者
  5. C#只允许启动一个WinFrom进程
  6. java seam 框架简介
  7. stun 协议 NAT穿透方式 简介
  8. 数字货币 BCH的混币神器CashShuffle
  9. netconf 网络配置协议 简介
  10. golang 读取 mysql null 字符串错误