顾名思义这个就是再消费的时候,不是之前的那哥用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();
}
}
}
}

测试代码

消费队列

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

此时队列还有

我们把它消费完

当只剩最后一个的时候

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

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

【并发】8、借助redis 实现多线程生产消费阻塞队列的更多相关文章

  1. 【并发】7、借助redis 实现多线程生产消费队列

    1.这是第一个简单的初始化版本,看起来比使用fqueue似乎更好用 package queue.redisQueue; import queue.fqueue.vo.TempVo; import re ...

  2. 【并发】6、借助FQueue 实现多线程生产消费队列

    1.这里先要说一下为什么会想到fqueue,因为这个是一个轻量级的消息队列框架,并且速度很快,用起来很方便,就是这样 当然后期考虑使用redis,这里先上一个fqueue的版本,后面有时间我再吧他改成 ...

  3. java并发编程工具类JUC第一篇:BlockingQueue阻塞队列

    Java BlockingQueue接口java.util.concurrent.BlockingQueue表示一个可以存取元素,并且线程安全的队列.换句话说,当多线程同时从 JavaBlocking ...

  4. Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍

    1.什么是阻塞队列? 所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了. 看一下线程的四种状态,首先是新创建一个线程,然后,通过s ...

  5. java多线程8:阻塞队列与Fork/Join框架

    队列(Queue),是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的. BlockingQueue 而阻塞队列BlockingQueue除了继承 ...

  6. Java多线程-新特征-阻塞队列ArrayBlockingQueue

    阻塞队列是Java5线程新特征中的内容,Java定义了阻塞队列的接口java.util.concurrent.BlockingQueue,阻塞队列的概念是,一个指定长度的队列,如果队列满了,添加新元素 ...

  7. python多线程生产消费

    #!/usr/bin/env python# -*- coding: utf-8 -*- from threading import Threadfrom Queue import Queueimpo ...

  8. java多线程系列10 阻塞队列模拟

    接下来的几篇博客会介绍下juc包下的相关数据结构 包含queue,list,map等 这篇文章主要模拟下阻塞队列. 下面是代码 import java.util.LinkedList; import ...

  9. 深入理解java:2.3.5. 并发编程concurrent包 之容器BlockingQueue(阻塞队列)

    1. 什么是阻塞队列? 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列. 这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空. 当队列满时,存储元素的线程会等待队列 ...

随机推荐

  1. JavaScript data types and data structures

    JavaScript data types and data structures Programming languages all have built-in data structures, b ...

  2. 【转】反编译获取任何微信小程序源码(完)

    一.前言最近在学习微信小程序开发,半个月学习下来,很想实战一下踩踩坑,于是就仿写了一个阿里妈妈淘宝客小程序的前端实现,过程一言难尽,差不多两周时间过去了,发现小程序的坑远比想象的要多的多!!在实际练手 ...

  3. nginx配置socket连接

    author: headsen  chen date:  2019-08-08 18:52:36 notice :个人原创 Nginx通过在客户端和后端服务器之间建立隧道来支持WebSockets通信 ...

  4. lintcode 394. Coins in a Line 、leetcode 292. Nim Game 、lintcode 395. Coins in a Line II

    变型:如果是最后拿走所有石子那个人输,则f[0] = true 394. Coins in a Line dp[n]表示n个石子,先手的人,是必胜还是必输.拿1个石子,2个石子之后都是必胜,则当前必败 ...

  5. Linux_CentOS软件安装调试 源代码包编译安装和 二进制包配置

    Linux 下源代码(C 语言)如何编译(安装) 1. 先安装源代码编译的软件 gcc,make,openssl 如下: yum install -y gcc make gcc-c++ openssl ...

  6. OMPL 在windows下的安装

    博客参考:https://blog.csdn.net/shitanding/article/details/82562702 和 https://bitbucket.org/ompl/omplapp/ ...

  7. oracle 的自定义的存储函数遇到的 package or function is in an invalid state

    转: oracle 的自定义的存储函数遇到的 package or function is in an invalid state 2017-10-28 11:08:17 major_tom 阅读数 ...

  8. spring-data-redis数据类型

    一.引入依赖 <!-- 缓存 --> <dependency> <groupId>redis.clients</groupId> <artifac ...

  9. osg gdal加载tif数据文件

    osg加载.tif地形数据文件 #ifdef _WIN32 #include <Windows.h> #endif // _WIN32 #include <iostream> ...

  10. Hello log4net——做一个实用好用的log4net的demo(转)

    log4net使用指南  (对配置解释比较全面细致,建议做完demo后多看) Log4Net使用详解(周公)——点击打开链接 Log4Net使用详解(续)周公——点击打开链接 点击打开链接 点击打开链 ...