redis实现队列

package org.jsirenia.queue;

import java.util.List;

public interface RedisQueue {

	void clear();

	boolean isEmpty();

	String peek();

	int add(String... source);

	List<String> peek(int count);

	List<String> take(int count);

	String take();

	int size();

}
package org.jsirenia.queue;

import java.util.Arrays;
import java.util.List;

import com.google.common.base.Objects;

import redis.clients.jedis.Jedis;
/**
 * redis隊列
 * 特點:
 * 簡單
 * 快速
 * 沒有消息確認機制
 * @author zhoujiaping
 */
public class DefaultRedisQueue implements RedisQueue{
	private Jedis redis;
	private String key;
	private int capacity;
	
	public DefaultRedisQueue config(Jedis redis,String key, int capacity){
		this.redis = redis;
		this.key = key;
		this.capacity = capacity;
		return this;
	}
	public static class RedisQueueException extends RuntimeException{
		public RedisQueueException(String string) {
			super(string);
		}
		private static final long serialVersionUID = 1L;
	}
	@Override
	public int add(String... source) {
		if(source == null){
			throw new RedisQueueException("参数不能为空");
		}
		if(source.length==0){
			return 0;
		}
		int successCount = source.length;
		if(capacity>0){
			Long len = redis.llen(key);
			int overSize =  (int) (len+source.length - capacity);
			if(overSize > 0){
				successCount = source.length - overSize;
				String[] target = new String[successCount];
				System.arraycopy(source, 0, target, 0, successCount);
				redis.lpush(key, target);
				return successCount;
			}else{
				redis.lpush(key, source);
			}
		}else{
			redis.lpush(key, source);
		}
		return successCount;
	}
	@Override
	public void clear() {
		redis.del(key);
	}
	@Override
	public boolean isEmpty() {
		return Objects.equal(redis.llen(key),0);
	}
	@Override
	public int size() {
		return redis.llen(key).intValue();
	}
	@Override
	public String peek() {
		return redis.lrange(key, 0, 0).get(0);
	}
	@Override
	public List<String> peek(int count) {
		return redis.lrange(key, 0, count-1);
	}
	@Override
	public List<String> take(int count){
		String script = "local msgList = redis.call('lrange', KEYS[1],ARGV[1],ARGV[2]); redis.call('ltrim',KEYS[1],ARGV[3],ARGV[4]); return msgList";
		Object result = redis.eval(script, Arrays.asList(key), Arrays.asList("0", String.valueOf(count-1), ""+count, "-1"));
		return (List<String>) result;
	}
	@Override
	public String take(){
		return redis.rpop(key);
	}
}

package org.jsirenia.queue;

import java.util.Arrays;
import java.util.List;

import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;

import redis.clients.jedis.Jedis;

/**
 * redis隊列 特點: 簡單 快速 沒有消息確認機制
 * 
 * @author zhoujiaping
 */
public class SpringRedisQueue implements RedisQueue {
	private RedisTemplate<String, String> redisTemplate;
	private String key;
	private int capacity;

	public void setRedisTemplate(RedisTemplate<String, String> redisTemplate) {
		this.redisTemplate = redisTemplate;
	}

	public static class RedisQueueException extends RuntimeException {
		public RedisQueueException(String string) {
			super(string);
		}

		private static final long serialVersionUID = 1L;
	}

	@Override
	public int add(final String... source) {
		return redisTemplate.execute(new RedisCallback<Integer>() {
			@Override
			public Integer doInRedis(RedisConnection conn) throws DataAccessException {
				Jedis redis = (Jedis) conn.getNativeConnection();
				if (source == null) {
					throw new RedisQueueException("参数不能为空");
				}
				if (source.length == 0) {
					return 0;
				}
				int successCount = source.length;
				if (capacity > 0) {
					Long len = redis.llen(key);
					int overSize = (int) (len + source.length - capacity);
					if (overSize > 0) {
						successCount = source.length - overSize;
						String[] target = new String[successCount];
						System.arraycopy(source, 0, target, 0, successCount);
						redis.lpush(key, target);
						return successCount;
					} else {
						redis.lpush(key, source);
					}
				} else {
					redis.lpush(key, source);
				}
				return successCount;
			}
		});
	}

	@Override
	public void clear() {
		redisTemplate.execute(new RedisCallback<Integer>() {
			@Override
			public Integer doInRedis(RedisConnection conn) throws DataAccessException {
				Jedis redis = (Jedis) conn.getNativeConnection();
				redis.del(key);
				return null;
			}
		});
	}

	@Override
	public boolean isEmpty() {
		return redisTemplate.execute(new RedisCallback<Boolean>() {
			@Override
			public Boolean doInRedis(RedisConnection conn) throws DataAccessException {
				Jedis redis = (Jedis) conn.getNativeConnection();
				Long len = redis.llen(key);
				return len == 0;
			}
		});
	}

	@Override
	public int size() {
		return redisTemplate.execute(new RedisCallback<Integer>() {
			@Override
			public Integer doInRedis(RedisConnection conn) throws DataAccessException {
				Jedis redis = (Jedis) conn.getNativeConnection();
				return redis.llen(key).intValue();
			}
		});
	}

	@Override
	public String peek() {
		return redisTemplate.execute(new RedisCallback<String>() {
			@Override
			public String doInRedis(RedisConnection conn) throws DataAccessException {
				Jedis redis = (Jedis) conn.getNativeConnection();
				return redis.lrange(key, 0, 0).get(0);
			}
		});
	}

	@Override
	public List<String> peek(final int count) {
		return redisTemplate.execute(new RedisCallback<List<String>>() {
			@Override
			public List<String> doInRedis(RedisConnection conn) throws DataAccessException {
				Jedis redis = (Jedis) conn.getNativeConnection();
				return redis.lrange(key, 0, count - 1);
			}
		});
	}

	@Override
	public List<String> take(final int count) {
		return redisTemplate.execute(new RedisCallback<List<String>>() {
			@SuppressWarnings("unchecked")
			@Override
			public List<String> doInRedis(RedisConnection conn) throws DataAccessException {
				Jedis redis = (Jedis) conn.getNativeConnection();
				String script = "local msgList = redis.call('lrange', KEYS[1],ARGV[1],ARGV[2]); redis.call('ltrim',KEYS[1],ARGV[3],ARGV[4]); return msgList";
				Object result = redis.eval(script, Arrays.asList(key),
						Arrays.asList("0", String.valueOf(count - 1), "" + count, "-1"));
				return (List<String>) result;
			}
		});
	}

	@Override
	public String take() {
		return redisTemplate.execute(new RedisCallback<String>() {
			@Override
			public String doInRedis(RedisConnection conn) throws DataAccessException {
				Jedis redis = (Jedis) conn.getNativeConnection();
				return redis.rpop(key);
			}
		});
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值