【并发】8、借助redis 实现多线程生产消费阻塞队…
2019-06-13 09:02:35来源:博客园 阅读 ()
顾名思义这个就是再消费的时候,不是之前的那哥用yield进行线程切换的操作,而是用线程等待阻塞的方式去执行,说实话我感觉效率不一定有之前那个好,
因为我对这种阻塞队列使用的时候,之前有发现阻塞队列,塞着塞着线程就会进入假死状态,这个很奇怪,但是有的时候又是好的,这个也不清楚到底是为什么
但是毕竟也是一种实现,我就写出来了看看吧
生产者
package queue.redisQueue; import queue.fqueue.vo.TempVo; import redis.clients.jedis.Jedis; import java.io.ByteArrayOutputStream; import java.io.ObjectOutputStream; import java.util.UUID; /** * @ProjectName: cutter-point * @Package: queue.redisQueue * @ClassName: RedisQueueProducter2 * @Author: xiaof * @Description: ${description} * @Date: 2019/6/12 16:29 * @Version: 1.0 */ public class RedisQueueProducter2 implements Runnable { private Jedis jedis; private String queueKey; public RedisQueueProducter2(Jedis jedis, String queueKey) { this.jedis = jedis; this.queueKey = queueKey; } @Override public void run() { while(true) { try { Thread.sleep((long) (Math.random() * 1000)); //不存在则创建,存在则直接插入 //向redis队列中存放数据 //生成数据 TempVo tempVo = new TempVo(); tempVo.setName(Thread.currentThread().getName() + ",time is:" + UUID.randomUUID()); //序列化为字节 ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(arrayOutputStream); objectOutputStream.writeObject(tempVo); arrayOutputStream.flush(); try { int i = 0; while(i < 10) { long num = jedis.lpush(queueKey.getBytes(), arrayOutputStream.toByteArray()); if(num > 0) { System.out.println("成功!"); break; } ++i; } } catch (Exception e) { System.out.println("失败!"); // long num = jedis.lpush(queueKey.getBytes(), arrayOutputStream.toByteArray()); } } catch (Exception e) { e.printStackTrace(); } } } }
消费者
package queue.redisQueue; import queue.fqueue.vo.EventVo; import redis.clients.jedis.Jedis; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.util.List; /** * @ProjectName: cutter-point * @Package: queue.redisQueue * @ClassName: RedisQueueConsume2 * @Author: xiaof * @Description: ${description} * @Date: 2019/6/12 16:40 * @Version: 1.0 */ public class RedisQueueConsume2 implements Runnable { private Jedis jedis; private String queueKey; public RedisQueueConsume2(Jedis jedis, String queueKey) { this.jedis = jedis; this.queueKey = queueKey; } @Override public void run() { while(true) { List<byte[]> bytesList = null; try{ //这种就是阻塞队列模式 bytesList = jedis.blpop(0, queueKey.getBytes()); } catch (Exception e) { } //反序列化对象 if(bytesList == null || bytesList.size() <= 0) { Thread.yield(); continue; } //获取第二个对象,就是我们的字节数组 System.out.println(new String(bytesList.get(0))); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytesList.get(1)); try { ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); EventVo eventVo = (EventVo) objectInputStream.readObject(); eventVo.doOperater(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } }
测试代码
消费队列
接下来我们把生产线程停掉
此时队列还有
我们把它消费完
当只剩最后一个的时候
可以进入下一步,好当队列为空的时候,我们再尝试去取数据的时候
队列会阻塞再这个地方,相当于是挂起线程
原文链接:https://www.cnblogs.com/cutter-point/p/11011084.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:面试总结
下一篇:jsp 九大内置对象
- redis缓存 2020-06-12
- Spring Boot 2.3.0 新特性Redis 拓扑动态感应 2020-06-11
- 作为一个面试官,我想问问你Redis分布式锁怎么搞? 2020-06-10
- 分布式锁没那么难,手把手教你实现 Redis 分布锁!|保姆级教 2020-06-08
- Redis企业级数据备份与恢复方案 2020-06-04
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash