redis线程阻塞原因排插_【并发】8、借助redis 实现多线程生产消费阻塞队列

顾名思义这个就是再消费的时候,不是之前的那哥用yield进行线程切换的操作,而是用线程等待阻塞的方式去执行,说实话我感觉效率不一定有之前那个好,

因为我对这种阻塞队列使用的时候,之前有发现阻塞队列,塞着塞着线程就会进入假死状态,这个很奇怪,但是有的时候又是好的,这个也不清楚到底是为什么

但是毕竟也是一种实现,我就写出来了看看吧

生产者

packagequeue.redisQueue;importqueue.fqueue.vo.TempVo;importredis.clients.jedis.Jedis;importjava.io.ByteArrayOutputStream;importjava.io.ObjectOutputStream;importjava.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 implementsRunnable {privateJedis jedis;privateString queueKey;publicRedisQueueProducter2(Jedis jedis, String queueKey) {this.jedis =jedis;this.queueKey =queueKey;

}

@Overridepublic voidrun() {while(true) {try{

Thread.sleep((long) (Math.random() * 1000));//不存在则创建,存在则直接插入//向redis队列中存放数据//生成数据

TempVo tempVo = newTempVo();

tempVo.setName(Thread.currentThread().getName()+ ",time is:" +UUID.randomUUID());//序列化为字节

ByteArrayOutputStream arrayOutputStream = newByteArrayOutputStream();

ObjectOutputStream objectOutputStream= newObjectOutputStream(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();

}

}

}

}

消费者

packagequeue.redisQueue;importqueue.fqueue.vo.EventVo;importredis.clients.jedis.Jedis;importjava.io.ByteArrayInputStream;importjava.io.IOException;importjava.io.ObjectInputStream;importjava.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 implementsRunnable {privateJedis jedis;privateString queueKey;publicRedisQueueConsume2(Jedis jedis, String queueKey) {this.jedis =jedis;this.queueKey =queueKey;

}

@Overridepublic voidrun() {while(true) {

List 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= newObjectInputStream(byteArrayInputStream);

EventVo eventVo=(EventVo) objectInputStream.readObject();

eventVo.doOperater();

}catch(IOException e) {

e.printStackTrace();

}catch(ClassNotFoundException e) {

e.printStackTrace();

}

}

}

}

测试代码

消费队列

接下来我们把生产线程停掉

此时队列还有

我们把它消费完

当只剩最后一个的时候

可以进入下一步,好当队列为空的时候,我们再尝试去取数据的时候

队列会阻塞再这个地方,相当于是挂起线程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值