1、这是第一个简单的初始化版本,看起来比使用fqueue似乎更好用

package queue.redisQueue;

import queue.fqueue.vo.TempVo;
import redis.clients.jedis.Jedis; import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.UUID; /**
* @ProjectName: cutter-point
* @Package: queue.redisQueue
* @ClassName: RedisQueueProducter
* @Author: xiaof
* @Description: ${description}
* @Date: 2019/6/12 9:44
* @Version: 1.0
*/
public class RedisQueueProducter implements Runnable { private Jedis jedis;
private String queueKey; public RedisQueueProducter(Jedis jedis, String queueKey) {
this.jedis = jedis;
this.queueKey = queueKey;
} @Override
public void run() { while(true) { try {
Thread.sleep(100); //不存在则创建,存在则直接插入
//向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; /**
* @ProjectName: cutter-point
* @Package: queue.redisQueue
* @ClassName: RedisQueueConsume
* @Author: xiaof
* @Description: ${description}
* @Date: 2019/6/12 10:08
* @Version: 1.0
*/
public class RedisQueueConsume implements Runnable { private Jedis jedis;
private String queueKey; public RedisQueueConsume(Jedis jedis, String queueKey) {
this.jedis = jedis;
this.queueKey = queueKey;
} @Override
public void run() { while(true) {
byte bytes[] = null;
try{
bytes = jedis.lpop(queueKey.getBytes());
} catch (Exception e) { } //反序列化对象
if(bytes == null || bytes.length <= 0) {
Thread.yield();
continue;
} ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
try {
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
EventVo eventVo = (EventVo) objectInputStream.readObject(); eventVo.doOperater(); } catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} }
}

测试,这里我踩了个坑,切记每个线程最好先获取一次资源,也就是

jedisPool.getResource() 
不然再并发操作的时候,2个线程同时使用一个连接,会导致服务无法使用
package queue.redisQueue;

import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig; import java.io.IOException; /**
* @ProjectName: cutter-point
* @Package: queue.redisQueue
* @ClassName: RedisQueueTest
* @Author: xiaof
* @Description: ${description}
* @Date: 2019/6/12 10:09
* @Version: 1.0
*/
public class RedisQueueTest { public static JedisPool jedisPool = null;
public static Jedis jedis; @Before
public void test0() {
//静态块,初始化加载,看来fQueue并不支持多进程操作,但是多线程是支持的
try { if(jedisPool == null) {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(10000);
jedisPoolConfig.setMaxIdle(2000);
jedisPoolConfig.setMaxWaitMillis(2000);
jedisPoolConfig.setTestOnBorrow(true);
jedisPoolConfig.setTestOnReturn(true); jedisPool = new JedisPool(jedisPoolConfig, "127.0.0.1", 17399, 2000, "ZTE$soft987", 0);
} if(jedis == null) {
jedis = jedisPool.getResource();
}
} catch (Exception e) {
e.printStackTrace();
}
} @Test
public void test1() throws InterruptedException { //读写取数据
for(int i = 0; i < 5; ++i) {
System.out.println("输出测试" + i);
RedisQueueProducter producter = new RedisQueueProducter(jedisPool.getResource(), "xiaof");
Thread t = new Thread(producter);
t.start();
} while(true) {
Thread.sleep(1000);
}
} @Test
public void test2() throws InterruptedException { //读写取数据
for(int i = 0; i < 2; ++i) {
System.out.println("输出测试" + i);
//切记一定要重新获取Resource,不然无法并发操作
RedisQueueConsume fqueueConsume = new RedisQueueConsume(jedisPool.getResource(), "xiaof");
Thread t = new Thread(fqueueConsume);
t.setDaemon(true);
t.start();
} while(true) {
Thread.sleep(1000);
}
} }

结果:

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

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

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

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

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

  3. python多线程生产消费

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

  4. 【java并发编程】Lock & Condition 协调同步生产消费

    一.协调生产/消费的需求 本文内容主要想向大家介绍一下Lock结合Condition的使用方法,为了更好的理解Lock锁与Condition锁信号,我们来手写一个ArrayBlockingQueue. ...

  5. redis和memcached有什么区别?redis的线程模型是什么?为什么单线程的redis比多线程的memcached效率要高得多(为什么redis是单线程的但是还可以支撑高并发)?

    1.redis和memcached有什么区别? 这个事儿吧,你可以比较出N多个区别来,但是我还是采取redis作者给出的几个比较吧 1)Redis支持服务器端的数据操作:Redis相比Memcache ...

  6. Python并发编程-生产消费模型

    生产消费模型初步 #产生两个子进程,Queue可以在子进程之间传递消息 from multiprocessing import Queue,Process import random import t ...

  7. kafka如何实现高并发存储-如何找到一条需要消费的数据(阿里)

    阿里太注重原理了:阿里问kafka如何实现高并发存储-如何找到一条需要消费的数据,kafka用了稀疏索引的方式,使用了二分查找法,其实很多索引都是二分查找法  二分查找法的时间复杂度:O(logn) ...

  8. Dyno-queues 分布式延迟队列 之 生产消费

    Dyno-queues 分布式延迟队列 之 生产消费 目录 Dyno-queues 分布式延迟队列 之 生产消费 0x00 摘要 0x01 前情回顾 1.1 设计目标 1.2 选型思路 0x02 产生 ...

  9. 测算Redis处理实际生产请求的QPS/TPS

    测算Redis处理实际生产请求的QPS/TPS Benchmark工具 redis发布版本中自带了redis-benchmark性能测试工具; 示例: 使用50个并发连接,发出100000个请求,每个 ...

随机推荐

  1. C# 复制数组容易踩到的坑--引用类型与值类型

    原文链接:https://my.oschina.net/u/3744313/blog/1794235 笔者近期做的项目里大量使用了数组,而在使用过程中,笔者曾经遇到了一个比较低级的问题:如何将一个数组 ...

  2. Cesium原理篇:Material【转】

    https://www.cnblogs.com/fuckgiser/p/6171245.html Shader 首先,在本文开始前,我们先普及一下材质的概念,这里推荐材质,普及材质的内容都是截取自该网 ...

  3. 【idea】idea远程调试代码

    一.前置条件 1.idea的代码和远程服务器代码保持一致 二.远程服务器配置 服务启动时,需要给jvm添加指定参数,进行启动 -agentlib:jdwp=transport=dt_socket,se ...

  4. Qt 中的对象模型(Object Model)

    原标题:Qt 中的对象模型(Object Model)90不太后,余生皆折腾 本节内容主要讲了 Qt 对象模型比标准 C++ 对象模型多了什么内容,并介绍了组成 Qt 对象模型基础的相关的类.最后说明 ...

  5. android -------- GifView 显示gif图片

    最近的项目需要在界面显示Gif动图,查找网络资料,总结了一下,分享一下, 一个GifView的gif图加载库以有效地显示GIF, 您可以启动,暂停和停止gifView 在app 的 build.gra ...

  6. ubuntu下如何开机自动执行自定义脚本?

    答: 将自定义脚本(假设自定义的脚本绝对路径为~/start_test.sh)添加到/etc/init.d/目录下,并更新系统启动项,命令如下: sudo cp ~/start_test.sh /et ...

  7. flutter Slider滑块组件

    滑块,允许用户通过滑动滑块来从一系列值中选择. import 'package:flutter/material.dart'; class SliderDemo extends StatefulWid ...

  8. typeScript中的数据类型

    /* typeScript中的数据类型 typescript中为了使编写的代码更规范,更有利于维护,增加了类型校验,在typescript中主要给我们提供了以下数据类型 布尔类型(boolean) 数 ...

  9. Centos7搭建OpenNebula云平台

    OpenNebula概述 OpenNebula是专门为云计算打造的开源系统,用户可以使用Xen.KVM.VMware等虚拟化软件一起打造企业云.利用OpenNebula可以轻松构建私有云.混合云.公开 ...

  10. 004-行为型-03-观察者模式(Observer)

    一.概述 当对象间存在一对多关系时,则使用观察者模式(Observer Pattern).比如,当一个对象被修改时,则会自动通知它的依赖对象. 定义了对象之间的一对多依赖,让多个观察者对象同时监听某一 ...