java的redis分布式锁_java中redis的分布式锁工具类

使用方式

try{if(PublicLock.getLock(lockKey)){//这里写代码逻辑,执行完后需要释放锁

PublicLock.freeLock(lockKey);

}

}catch(Exception e) {//产生异常也需要释放锁

PublicLock.freeLock(lockKey);

LOGGER.error(e);

}

redis的分布式锁工具类的基础类

package com.qlchat.redis.cache;

import java.util.*;

import org.apache.commons.lang.StringUtils;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import redis.clients.jedis.Jedis;

import redis.clients.jedis.exceptions.JedisException;

import com.qlchat.common.util.JedisUtil;

import com.qlchat.common.util.QlchatUtil;

/**

* 默认操作redis库是DEFAULT_REDIS_DB = 1

* @author zhangk

*

*/

public class BaseCache extends JedisUtil {

private static Logger log = LoggerFactory.getLogger(BaseCache.class);

private static Long REDIS_INCR_MAX = 4294967294L;

private static int DEFAULT_REDIS_DB = 0;//默认redis库

/**

*

* 设置value

*

* @since 1.0.0

*/

public static void setValue(String key, String value, Integer expire) {

Jedis jedis = getJedis();

try {

// 如果存在则插入覆盖,如果不存在则初始化

if(expire != null){

Long ttl = jedis.ttl(key);

jedis.set(key, value);

if(ttl != null && ttl > 0){

jedis.expire(key, ttl.intValue());

}else{

jedis.expire(key, expire);

}

}else{

jedis.set(key, value);

}

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

}

public static void setHashFieldValue(String key, String field, String value) {

setHashFieldValue(key, field, value, null);

}

/**

*

* 更新或新增缓存信息

*

* @since 1.0.0

*/

public static void setHashFieldValue(String key, String field, String value, Integer expire) {

Jedis jedis = getJedis();

try {

if(expire != null){

Long ttl = jedis.ttl(key);

jedis.hset(key, field, value);

if(ttl != null && ttl > 0){

jedis.expire(key, ttl.intValue());

}else{

jedis.expire(key, expire);

}

}else{

jedis.hset(key, field, value);

}

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

}

public static void setHashMapValue(String key, Map map, Integer expire) {

setHashMapValue(key, map, DEFAULT_REDIS_DB, expire);

}

/**

*

* 更新或新增缓存信息

*

* @exception

* @since 1.0.0

*/

public static void setHashMapValue(String key, Map map, int db, Integer expire) {

Jedis jedis = getJedis();

try {

if(expire != null){

Long ttl = jedis.ttl(key);

jedis.hmset(key, map);

if(ttl != null && ttl > 0){

jedis.expire(key, ttl.intValue());

}else{

jedis.expire(key, expire);

}

}else{

jedis.hmset(key, map);

}

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

}

public static String getValue(String key){

return getValue(key, DEFAULT_REDIS_DB);

}

public static String getValue(String key, int db) {

if (StringUtils.isBlank(key)) {

return null;

}

Jedis jedis = getJedis();

String val = null;

try {

val = jedis.get(key);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val != null ? val : StringUtils.EMPTY;

}

public static String getHashFieldValue(String key, String field) {

return getHashFieldValue(key, field, DEFAULT_REDIS_DB);

}

/**

*

* 获取Value Map 的值

*

* @since 1.0.0

*/

public static String getHashFieldValue(String key, String field, int db) {

if (StringUtils.isBlank(key) || StringUtils.isBlank(field)) {

return null;

}

Jedis jedis = getJedis();

String val = null;

try {

val = jedis.hget(key, field);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 获取field是否存在

* @param key key

* @param field field

* @param db db

* @return boolean

*/

public static boolean getHashFieldExist(String key, String field, int db) {

if (StringUtils.isBlank(key) || StringUtils.isBlank(field)) {

return false;

}

Jedis jedis = getJedis();

try {

return jedis.hexists(key, field);

} catch (Exception e) {

e.printStackTrace();

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return false;

}

public static Map getHashAll(String key){

return getHashAll(key, DEFAULT_REDIS_DB);

}

public static Map getHashAll(String key, int db) {

if (StringUtils.isBlank(key)) {

return null;

}

Jedis jedis = getJedis();

Map val = null;

try {

val = jedis.hgetAll(key);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

e.printStackTrace();

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val == null ? new HashMap() : val;

}

public static void delHashFiled(String key, String... fields) {

delHashFiled(key, DEFAULT_REDIS_DB, fields);

}

/**

*

* 删除一个或多个field

*

* @since 1.0.0

*/

public static void delHashFiled(String key, int db, String... fields) {

if (StringUtils.isBlank(key) || fields == null || fields.length < 1) {

return;

}

Jedis jedis = getJedis();

try {

jedis.hdel(key, fields);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

}

public static void delKey(String... key) {

delKey(DEFAULT_REDIS_DB, key);

}

/**

*

* 删除一个或多个key

*

* @since 1.0.0

*/

public static void delKey(int db, String... key) {

if (key == null || key.length < 1) {

return;

}

Jedis jedis = getJedis();

try {

//jedis.select(db);

jedis.del(key);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

}

/**

* 自增

* @param incr >0表示加 <0表示减

*/

public static Long hincr(String key, String field, Long incr, Integer expire) {

Long val = null;

Jedis jedis = getJedis();

try {

if(expire != null){

Long ttl = jedis.ttl(key);

val = jedis.hincrBy(key, field, incr);

if (val >= REDIS_INCR_MAX ) {//Integer无符号的最大数

jedis.set(key, "0");

}

if(ttl != null && ttl > 0){

jedis.expire(key, ttl.intValue());

}else{

jedis.expire(key, expire);

}

}else{

val = jedis.hincrBy(key, field, incr);

if (val >= REDIS_INCR_MAX ) {//Integer无符号的最大数

jedis.set(key, "0");

}

}

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 自增 1

* @return 返回操作后的结果

*/

public static Long incr(String key) {

Long val = null;

Jedis jedis = getJedis();

try {

//jedis.select(DEFAULT_REDIS_DB);

val = jedis.incr(key);

if (val >= REDIS_INCR_MAX ) {//Integer无符号的最大数

jedis.set(key, "0");

}

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 增加自定义步长

*/

public static Long incrBy(String key, Long incr) {

Long val = null;

Jedis jedis = getJedis();

try {

//jedis.select(DEFAULT_REDIS_DB);

val = jedis.incrBy(key,incr);

if (val >= REDIS_INCR_MAX ) {//Integer无符号的最大数

jedis.set(key, "0");

}

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 用于做原子锁操作 HSETNX key field value

* 将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在。

* 若域 field 已经存在,该操作无效。

* 如果 key 不存在,一个新哈希表被创建并执行 HSETNX 命令。

* 设置成功,返回 1 。

如果给定域已经存在且没有操作被执行,返回 0 。

*/

public static Long setValueIfNotExist(String key, String field, String value) {

Long val = 0L;

Jedis jedis = getJedis();

try {

int seconds = 3 * 60;//3min

//jedis.select(RedisLiveKeyConstants.LIVE_TEMP_DB);

Long ttl = jedis.ttl(key);

val = jedis.hsetnx(key, field, value);

if(val > 0){

jedis.expire(key, seconds);

}else{//防止设置过期时间失败

if(ttl != null && (ttl == -1 || ttl > seconds)){

//获得的是一个失效的key, 第一次还是失败,第二次就好了

jedis.del(key);

}

}

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。

假如 key 不存在,则创建一个只包含 member 元素作成员的集合。

当 key 不是集合类型时,返回一个错误。

* @param key

* @param members

* @return

*/

//public static Long sadd(String key, Integer expire, String... members) {

//return sadd(key, DEFAULT_REDIS_DB, expire, members);

//}

public static Long saddSet(String key,Integer expire, String... members){

Long val = null;

Jedis jedis = getJedis();

try {

if (members != null && members.length > 0) {

if(expire != null){

Long ttl = jedis.ttl(key);

val = jedis.sadd(key, members);

if(ttl != null && ttl > 0){

jedis.expire(key, ttl.intValue());

}else{

jedis.expire(key, expire);

}

}else{

val = jedis.sadd(key, members);

}

}

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。

* @param key

* @param members

* @return

*/

public static Long sdel(String key, String... members) {

Long val = null;

Jedis jedis = getJedis();

try {

val = jedis.srem(key, members);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 判断 member 元素是否集合 key 的成员。

* true 存在

* @param key

* @param member

* @return

*/

public static boolean sismember(String key, String member) {

boolean val = false;

Jedis jedis = getJedis();

try {

//jedis.select(DEFAULT_REDIS_DB);

val = jedis.sismember(key, member);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 返回集合 key 中的所有成员。不存在的 key 被视为空集合。

* @param key

* @return

*/

public static Set smembers(String key) {

Set val = null;

Jedis jedis = getJedis();

try {

//jedis.select(DEFAULT_REDIS_DB);

val = jedis.smembers(key);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 返回集合随机元素

* @param key

* @return

*/

public static List srandom(String key,int num) {

List list = new ArrayList();

Jedis jedis = getJedis();

try {

list = jedis.srandmember(key,num);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return list;

}

/**

* 移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。

* @param key

* @return

*/

public static Long slen(String key) {

Long val = null;

Jedis jedis = getJedis();

try {

val = jedis.scard(key);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 移除并返回集合中的一个随机元素。

* @param key

* @return

*/

public static String spop(String key) {

String val = null;

Jedis jedis = getJedis();

try {

val = jedis.spop(key);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 检查给定 key 是否存在。

* @param key

* @return

*/

public static boolean exists(String key) {

boolean val = false;

Jedis jedis = getJedis();

try {

val = jedis.exists(key);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 将一个或多个值 value 插入到列表 key 的表尾(最右边)。

* @param key

* @param value

* @return

*/

public static Long rpush(String key, Integer db, Integer expire, String... value) {

Long val = null;

Jedis jedis = getJedis();

try {

if(expire != null){

Long ttl = jedis.ttl(key);

val = jedis.rpush(key, value);

if(ttl != null && ttl > 0){

jedis.expire(key, ttl.intValue());

}else{

jedis.expire(key, expire);

}

}else{

val = jedis.rpush(key, value);

}

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 将一个或多个值 value 插入到列表 key 的表尾(最左边)。

* @param key

* @param value

* @return

*/

public static Long lpush(String key, Integer db, Integer expire, String... value) {

Long val = null;

Jedis jedis = getJedis();

try {

if(expire != null){

Long ttl = jedis.ttl(key);

val = jedis.lpush(key, value);

if(ttl != null && ttl > 0){

jedis.expire(key, ttl.intValue());

}else{

jedis.expire(key, expire);

}

}else{

val = jedis.lpush(key, value);

}

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 列表修剪,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。

* @param key

* @param start

* @param stop

*/

public static void ltrim(String key, int start, int stop) {

Jedis jedis = getJedis();

try {

jedis.ltrim(key, start, stop);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

}

/**

* 将一个或多个值 value 弹出到列表 key 的表尾(最左边)。

* @param key

* @param value

* @return

*/

public static String rpop(String key, Integer db) {

String val = null;

Jedis jedis = getJedis();

try {

val = jedis.rpop(key);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。

* @param key

* @param db

* @param start

* @param end

* @return

*/

public static List lrange(String key, Integer db, long start, long end) {

List val = null;

Jedis jedis = getJedis();

try {

val = jedis.lrange(key, start, end);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 返回列表 key 的长度。

* @param key

* @param db

* @return

*/

public static Long llen(String key, Integer db){

Long val = null;

Jedis jedis = getJedis();

try {

val = jedis.llen(key);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val == null?0:val;

}

/**

* 返回列表 key 的长度。

* @param key

* @param db

* @return

*/

public static Long hlen(String key){

Long val = null;

Jedis jedis = getJedis();

try {

val = jedis.hlen(key);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val == null?0:val;

}

/**

* 设置过期时间

* @param key

* @return

*/

public static Integer ttl(String key){

if(StringUtils.isBlank(key)) {

return -2;

}

Jedis jedis = getJedis();

Long val = -2L;

try {

val = jedis.ttl(key);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val.intValue();

}

/**

* HyperLogLog add

* @param key

* @return

*/

public static Integer pfadd(String key, String... elements){

if(StringUtils.isBlank(key)) {

return -2;

}

Jedis jedis = getJedis();

Long val = -2L;

try {

val = jedis.pfadd(key, elements);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val.intValue();

}

/**

* HyperLogLog count

* @param key

* @return

*/

public static Long pfcount(String key){

if(StringUtils.isBlank(key)) {

return 0L;

}

Jedis jedis = getJedis();

Long val = 0L;

try {

val = jedis.pfcount(key);

} catch (JedisException e) {

log.error(e.getMessage(),e);

} catch (Exception e) {

log.error(e.getMessage(),e);

} finally {

if (jedis != null) {

jedis.close();

}

}

return val;

}

/**

* 更新直播间最后浏览时间

* @param userId

* @param liveId

* @return

*/

public static Long zaddLastBrowse(String userId, String liveId, Date date){

if(QlchatUtil.isEmpty(userId) || QlchatUtil.isEmpty(liveId)){

return null;

}

String cacheKey = "LAST_BROWSE_".concat(userId);

double score = date.getTime();

return zadd(cacheKey, liveId, score);

}

/**

* 按照score递减分页获取最新浏览的liveId

* @param userId

* @param start

* @param end

* @return

*/

public static Set zrevRangeLastBrowse(String userId, int pageNum, int pageSize){

if(QlchatUtil.isEmpty(userId)){

return null;

}

int start = (pageNum - 1) * pageSize;

int end = start + pageSize - 1;

String cacheKey = "LAST_BROWSE_".concat(userId);

return zrevrange(cacheKey, start, end);

}

public static Long zcardLastBrowse(String userId){

if(QlchatUtil.isEmpty(userId)){

return null;

}

String cacheKey = "LAST_BROWSE_".concat(userId);

return zcard(cacheKey);

}

public static Long zremLastBrowse(String userId){

if(QlchatUtil.isEmpty(userId)){

return null;

}

String cacheKey = "LAST_BROWSE_".concat(userId);

Long countNum = zcard(cacheKey);

if(countNum > 60){

return zremrangeByRank(cacheKey, 0, (countNum.intValue() - 60));

}

return null;

}

}

redis分布式锁工具类

package com.qlchat.redis.cache;

import com.qlchat.common.constants.CommonConstants;

import com.qlchat.common.constants.RedisLiveKeyConstants;

import com.qlchat.common.helper.*;

import com.qlchat.component.redis.template.*;

public class PublicLock {

private static final Long TOTAL_WAIT_SENCODS = 10 * 1000L;// 10s获取不到算超时

private static final Integer REPLY_WAIT_SENCODS = 5;// 重试获取锁间隔时间ms

public static ValueRedisTemplate valueRedisTemplate;

public static HashRedisTemplate hashRedisTemplate;

public static ListRedisTemplate listRedisTemplate;

public static SetRedisTemplate setRedisTemplate;

public static HyperLogLogTemplate hyperLogLogTemplate;

static {

valueRedisTemplate = SpringHelper.getBean(ValueRedisTemplate.class);

hashRedisTemplate = SpringHelper.getBean(HashRedisTemplate.class);

listRedisTemplate = SpringHelper.getBean(ListRedisTemplate.class);

setRedisTemplate = SpringHelper.getBean(SetRedisTemplate.class);

hyperLogLogTemplate = SpringHelper.getBean(HyperLogLogTemplate.class);

}

/**

* 获取操作锁

* 需要写线程去过时历史失败的锁

* @return true 获取成功,false获取失败

* @throws InterruptedException

*/

public static boolean getLock(String lockKey, Long waitSencods) throws InterruptedException{

long t1 = System.currentTimeMillis();

boolean isSuccess = false;

while(!isSuccess){

if (System.currentTimeMillis() <= t1 + waitSencods) {

isSuccess = tryLock(lockKey, lockKey);

if(!isSuccess){

Thread.sleep(REPLY_WAIT_SENCODS);//sleep10ms

}

}else{//超过等待时间,返回失败

break;

}

}

return isSuccess;

}

/**

* 获取操作锁

* @return true 获取成功,false获取失败

* @throws InterruptedException

*/

public static boolean getLock(String lockKey) throws InterruptedException{

Long waitSencods = TOTAL_WAIT_SENCODS;

return getLock(lockKey, waitSencods);

}

/**

* 释放锁

*/

public static void freeLock(String lockKey){

BaseCache.delKey(RedisLiveKeyConstants.LIVE_TEMP_DB, lockKey);

}

/**

* 锁是否存在

* @param lockKey

* @return

*/

public static boolean isLock(String lockKey) {

return BaseCache.getHashFieldExist(lockKey, lockKey, 0);

}

/**

* 尝试获取锁

* @return

*/

private static boolean tryLock(String lockKey, String field){

boolean isSuccess = false;

long setValue = BaseCache.setValueIfNotExist(lockKey, field, CommonConstants.YesOrNo.YES);//返回1则成功

if(setValue > 0){

isSuccess = true;

}

return isSuccess;

}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值