1、redis.properties

##redisIP地址
#redis.host=10.14.2.212
redis.host=127.0.0.1
##redis默认端口号
redis.port=6379
#redis密码
redis.pass=a7217sec!@# ##redis.database=0 ##指定使用第几个库 redis.maxIdle=300
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true
redis.timeout=1000 redis.pool.maxActive=200
redis.pool.maxIdle=50
redis.pool.minIdle=0
redis.pool.maxWait=15000
##向调用者输出链接资源时,是否检测是否有效,如果无效则从连接池中移除,尝试继续获取,默认为false,建议保留默认值
redis.pool.testOnBorrow=false
##向连接池“归还”链接时,是否检测“链接”对象的有效性。默认为false。建议保持默认值.
redis.pool.testOnReturn=false
##maxActive: 链接池中最大连接数,默认为8.
##maxIdle: 链接池中最大空闲的连接数,默认为8.
##minIdle: 连接池中最少空闲的连接数,默认为0.
##maxWait: 当连接池资源耗尽时,调用者最大阻塞的时间,超时将跑出异常。单位,毫秒数;默认为-1.表示永不超时.
##minEvictableIdleTimeMillis: 连接空闲的最小时间,达到此值后空闲连接将可能会被移除。负值(-1)表示不移除。
##softMinEvictableIdleTimeMillis: 连接空闲的最小时间,达到此值后空闲链接将会被移除,且保留“minIdle”个空闲连接数。默认为-1.
##numTestsPerEvictionRun: 对于“空闲链接”检测线程而言,每次检测的链接资源的个数。默认为3.
##testOnBorrow: 向调用者输出“链接”资源时,是否检测是有有效,如果无效则从连接池中移除,并尝试获取继续获取。默认为false。建议保持默认值.
##testOnReturn: 向连接池“归还”链接时,是否检测“链接”对象的有效性。默认为false。建议保持默认值.
##testWhileIdle:false 向调用者输出“链接”对象时,是否检测它的空闲超时;默认为false。如果“链接”空闲超时,将会被移除。建议保持默认值.
##timeBetweenEvictionRunsMillis: “空闲链接”检测线程,检测的周期,毫秒数。如果为负值,表示不运行“检测线程”。默认为-1.
##whenExhaustedAction: 当“连接池”中active数量达到阀值时,即“链接”资源耗尽时,连接池需要采取的手段, 默认为1:
## -> 0 : 抛出异常,
## -> 1 : 阻塞,直到有可用链接资源
## -> 2 : 强制创建新的链接资源

2、spring-redis.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:annotation-config /> <!-- 引入外部属性文件. -->
<context:property-placeholder location="classpath*:redis.properties" ignore-unresolvable="true" /> <!-- 注册 -->
<context:component-scan base-package="com.xiaomei.queue.redis.demo01"/> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!--<property name="maxTotal" value="${redis.pool.maxActive}" />-->
<!--最大空闲连接数 -->
<property name="maxIdle" value="${redis.pool.maxIdle}" />
<!--初始化连接数 -->
<property name="minIdle" value="${redis.pool.minIdle}" />
<!--最大等待时间 -->
<property name="maxWaitMillis" value="${redis.pool.maxWait}" />
<!--对拿到的connection进行validateObject校验 -->
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
<!--在进行returnObject对返回的connection进行validateObject校验 -->
<property name="testOnReturn" value="${redis.pool.testOnReturn}" />
<!--定时对线程池中空闲的链接进行validateObject校验 -->
<property name="testWhileIdle" value="false" />
</bean> <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="${redis.host}" p:port="${redis.port}" p:password="mxb123" p:pool-config-ref="poolConfig"/> <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
        <!-- 采用jdk序列 -->
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
</bean>   <!-- 发送邮件的队列,这边只是个例子 -->
<bean id="sentEmailQueue" class="com.xiaomei.queue.redis.demo01.SendEmailQueue">
<property name="redisQueue" >
<bean class="com.xiaomei.queue.redis.demo01.RedisQueue" destroy-method="destroy">
<property name="redisTemplate" ref="redisTemplate"></property>
<property name="queueName" value="email"></property>
</bean>
</property>
</bean> </beans>

3、IRedisQueue.java

package com.xiaomei.queue.redis.demo01;

import java.util.concurrent.TimeUnit;

/**
* @author xiaomei
* @version V1.0
* @Title: IRedisQueue
* @Package com.xiaomei.queue.redis.demo01
* @Description:
* @date 11/7/17
*/
public interface IRedisQueue<T> { /**
* 从头开始拿
* 拿出,没有就等待
* @return
* @throws InterruptedException
*/
public T take() throws InterruptedException; /**
* 从尾开始拿
* 拿出,没有就等待
* @return
* @throws InterruptedException
*/
public T takeOpposite() throws InterruptedException; /**
* 从头开始拿
* 拿出,没有就等待 seconds 秒
* @param seconds
* @return
* @throws InterruptedException
*/
public T poll(int seconds) throws InterruptedException; /**
* 从头开始拿
* 拿出,没有就等待 seconds 秒
* @param seconds
* @return
* @throws InterruptedException
*/
public T pollOpposite(int seconds) throws InterruptedException; /**
* 从尾开始放
* 入队
* @param value
* @return
* @throws InterruptedException
*/
public void add(T value); /**
* 从头开始放
* 入队
* @param value
* @return
* @throws InterruptedException
*/
public void addOpposite(T value); //
// /**
// * 从头开始删除
// * @return
// */
// public T remove();
//
//
// /**
// * 从尾开始删除
// * @return
// */
// public T removeOpposite();
// /**
* 删除所有
*/
public void clearAll(); }

4、RedisQueue.java

package com.xiaomei.queue.redis.demo01;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.RedisConnectionUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils; import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* @author xiaomei
* @version V1.0
* @Title: RedisQueue
* @Package com.xiaomei.queue.redis.demo01
* @Description:
* @date 11/7/17
*/
public class RedisQueue<T> implements InitializingBean,DisposableBean,IRedisQueue<T> { //队列名称
public String queueName;
//原生key
private byte[] rawKey; private RedisTemplate redisTemplate;
private RedisConnectionFactory factory;
private RedisConnection connection; //为了堵塞
private BoundListOperations<String, T> listOperations;
private Lock lock = new ReentrantLock();//基于底层IO阻塞考虑 如果分布式的话,就是用分式式的锁 @Override
public T take() throws InterruptedException {
return poll(0);
} @Override
public T takeOpposite() throws InterruptedException {
return pollOpposite(0);
} @Override
public T poll(int seconds) throws InterruptedException {
lock.lockInterruptibly();
try{
List<byte[]> results = connection.bRPop(seconds, rawKey);
if(CollectionUtils.isEmpty(results)){
return null;
}
return (T)redisTemplate.getValueSerializer().deserialize(results.get(1));
}finally{
lock.unlock();
}
} @Override
public T pollOpposite(int seconds) throws InterruptedException {
lock.lockInterruptibly();
try{
List<byte[]> results = connection.bLPop(seconds, rawKey);
if(CollectionUtils.isEmpty(results)){
return null;
}
return (T)redisTemplate.getValueSerializer().deserialize(results.get(1));
}finally{
lock.unlock();
}
} @Override
public void add(T value) {
listOperations.rightPush(value);
} @Override
public void addOpposite(T value) {
listOperations.leftPush(value);
} @Override
public void clearAll() {
// listOperations.
} @Override
public void afterPropertiesSet() throws Exception {
factory = redisTemplate.getConnectionFactory();
connection = RedisConnectionUtils.getConnection(factory);
rawKey = redisTemplate.getKeySerializer().serialize(queueName);
listOperations = redisTemplate.boundListOps(queueName);
} @Override
public void destroy() throws Exception {
RedisConnectionUtils.releaseConnection(connection, factory);
} public void setQueueName(String queueName) {
this.queueName = queueName;
} public void setRedisTemplate(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
} }

5、SendEmailQueue

package com.xiaomei.queue.redis.demo01;

import com.xiaomei.queue.redis.demo01.entity.EmailEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.RedisTemplate; /**
* @author xiaomei
* @version V1.0
* @Title: SendEmailQueue
* @Package com.xiaomei.queue.redis.demo01
* @Description:
* @date 11/7/17
*/
public class SendEmailQueue implements Runnable{ //@Autowired
private IRedisQueue<EmailEntity> redisQueue; public IRedisQueue<EmailEntity> getRedisQueue() {
return redisQueue;
} public void setRedisQueue(IRedisQueue<EmailEntity> redisQueue) {
this.redisQueue = redisQueue;
} public void sentEmail(EmailEntity emailEntity) {
redisQueue.add(emailEntity);
} public EmailEntity getEmail() throws InterruptedException {
return redisQueue.poll(1);
} @Override
public void run() {
try {
while (true){
System.out.println("take"+getEmail());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-redis.xml");
SendEmailQueue sendEmailQueue = (SendEmailQueue) applicationContext.getBean("sentEmailQueue");
// Thread thread = new Thread(){
// @Override
// public void run() {
// for (int i = 0 ; i <100 ; i++){
// EmailEntity emailEntity = new EmailEntity();
// emailEntity.setEmailAddr(i+"-- - @qq.com");
// emailEntity.setUserName("name:"+i);
// sendEmailQueue.sentEmail(emailEntity);
// }
// }
// };
// thread.run();
sendEmailQueue.run();
}
}

6、EmailEntity.java   注意必须 实现Serializeable 不然不能序列化

package com.xiaomei.queue.redis.demo01.entity;

import java.io.Serializable;

/**
* @author 梅谢兵
* @version V1.0
* @Title: EmailEntity
* @Package com.xiaomei.queue.redis.demo01.entity
* @Description:
* @date 11/7/17
*/
public class EmailEntity implements Serializable { private String userName;
private String emailAddr; public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public String getEmailAddr() {
return emailAddr;
} public void setEmailAddr(String emailAddr) {
this.emailAddr = emailAddr;
} @Override
public String toString() {
return "EmailEntity{" +
"userName='" + userName + '\'' +
", emailAddr='" + emailAddr + '\'' +
'}';
}
}

采用的是生产者和消费者的模式。

最后加上一直图

Java Redis+Spring-data-redis 队列 单机版的更多相关文章

  1. Spring Data Redis实现消息队列——发布/订阅模式

    一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式.利用redis这两种场景的消息队列都能够实现. 定义:生产者消费者模式:生产者生产消息放到队列里,多个消费者同时监听队列, ...

  2. 使用Spring Data Redis操作Redis(单机版)

    说明:请注意Spring Data Redis的版本以及Spring的版本!最新版本的Spring Data Redis已经去除Jedis的依赖包,需要自行引入,这个是个坑点.并且会与一些低版本的Sp ...

  3. Spring Data Redis—Pub/Sub(附Web项目源码)

    一.发布和订阅机制 当一个客户端通过 PUBLISH 命令向订阅者发送信息的时候,我们称这个客户端为发布者(publisher). 而当一个客户端使用 SUBSCRIBE 或者 PSUBSCRIBE ...

  4. Spring Data Redis—Pub/Sub(附Web项目源码) (转)

    一.发布和订阅机制 当一个客户端通过 PUBLISH 命令向订阅者发送信息的时候,我们称这个客户端为发布者(publisher). 而当一个客户端使用 SUBSCRIBE 或者 PSUBSCRIBE ...

  5. spring data redis RedisTemplate操作redis相关用法

    http://blog.mkfree.com/posts/515835d1975a30cc561dc35d spring-data-redis API:http://docs.spring.io/sp ...

  6. spring mvc Spring Data Redis RedisTemplate [转]

    http://maven.springframework.org/release/org/springframework/data/spring-data-redis/(spring-data包下载) ...

  7. Spring Data Redis简介以及项目Demo,RedisTemplate和 Serializer详解

    一.概念简介: Redis: Redis是一款开源的Key-Value数据库,运行在内存中,由ANSI C编写,详细的信息在Redis官网上面有,因为我自己通过google等各种渠道去学习Redis, ...

  8. Spring data redis的一个bug

    起因 前两天上线了一个新功能,导致线上业务的缓存总是无法更新,报错也是非常奇怪,redis.clients.jedis.exceptions.JedisConnectionException: Unk ...

  9. spring data redis 理解

    前言 Spring Data Redis project,应用了Spring概念来开发使用键值形式的数据存储的解决方案.我们(官方)提供了一个 "template" ,这是一个高级 ...

  10. Spring Data Redis 详解及实战一文搞定

    SDR - Spring Data Redis的简称. Spring Data Redis提供了从Spring应用程序轻松配置和访问Redis的功能.它提供了与商店互动的低级别和高级别抽象,使用户免受 ...

随机推荐

  1. ABP中的AutoMapper

    在我们的业务中经常需要使用到类型之间的映射,特别是在和前端页面进行交互的时候,我们需要定义各种类型的Dto,并且需要需要这些Dto和数据库中的实体进行映射,对于有些大对象而言,需要赋值太多的属性,这样 ...

  2. java生成验证码结合springMVC

    在用户登录的时候,为了防止机器人攻击都会设置输入验证码,本篇文章就是介绍java如何生成验证码并使用在springMVC项目中的. 第一步:引入生成图片验证码的工具类 import java.awt. ...

  3. 【自学系列一】HTML5大前端学习路线+视频教程(完整版)

    今年,本公司全新发布了囊括Java.HTML5前端.大数据.Python爬虫.全链UI设计.软件测试.Unity 3D.Go语言等多个技术方向的全套视频. 面对这么多的知识点,有的盆友就麻爪了…… 我 ...

  4. oracle sqlplus命令

    show和set命令是两条用于维护SQL*Plus系统变量的命令 SQL> show all --查看所有68个系统变量值 SQL> show user --显示当前连接用户 SQL> ...

  5. Django数据库基本操作(MySQL)

    以一个示例工程为例: 下面是工程文件目录: untited为项目文件(一般与根目录同名),CommunityModel为一个定义数据库模型的APP 一.定义模型 1.首先配置好数据库,在untited ...

  6. Dockfile文件解析

    1. Dockerfile内容基础知识 每条保留字指令都必须为大写字母且后面要跟随至少一个参数 指令按照从上到下,顺序执行 #表示注释 每条指令都会创建一个新的镜像层,并对镜像进行提交 2. Dock ...

  7. 怎样判断当前浏览器是PC浏览器还是手机浏览器

    可以通过检测navigator.userAgent字段中是否有"mobi"字段来检测是PC浏览器还是手机浏览器: /mobi/i.test(window.navigator.use ...

  8. Golang高并发抓取HTML图片

    Golang高并发抓取HTML图片 使用准备 1.安装Golang 2.下载爬虫包 go get -v github.com/hunterhug/marmot/util go get -v githu ...

  9. 在论坛中出现的比较难的sql问题:41(循环替换 循环替换关键字)

    原文:在论坛中出现的比较难的sql问题:41(循环替换 循环替换关键字) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路.

  10. List<T> or IList<T>

      If you are exposing your class through a library that others will use, you generally want to expos ...