(1)需要导入的包

<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
</dependency>

(2)JedisUtil类


import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool; import java.util.Collections; /**
* 不采用springTemplate 的操作类
* 因为springTemplate 的SetNx 非原子性,可能导致锁永久锁住,释放失败
*/
@Component("jedisUtil")
public class JedisUtil { private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";
private static final Long RELEASE_SUCCESS = 1L; @Autowired
private JedisPool jedisPool; /**
* 尝试获取分布式锁
* @param lockKey 锁
* @param requestId 请求标识
* @param expireTime 超期时间
* @return 是否获取成功
*/
public boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) {
Jedis jedis = null;
try{
jedis = jedisPool.getResource();
String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
if (LOCK_SUCCESS.equals(result)) {
return true;
}
} finally {
//归还 jedis 连接
if(jedis != null){
jedis.close();
}
}
return false;
} /**
* 释放分布式锁
* @param lockKey 锁
* @param requestId 请求标识
* @return 是否释放成功
*/
public boolean releaseDistributedLock(String lockKey, String requestId) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
if (RELEASE_SUCCESS.equals(result)) {
return true;
}
} finally {
//归还 jedis 连接
if(jedis != null){
jedis.close();
}
}
return false;
} /**
* 设置值并设置超时时间
* @param key
* @param value
* @param expireTime
* @return
*/
public Long rpushString(String key, String value, int expireTime){
Jedis jedis = null;
Long result = 0L;
try {
jedis = jedisPool.getResource();
result = jedis.rpush(key, value);
if(result > 0){
jedis.expire(key,expireTime);
}
} finally {
if(jedis != null){
jedis.close();
}
}
return result;
} /**
* 批量插入
* @param key
* @param values
* @param expireTime
* @return
*/
public Long batchRpushString(String key, String[] values, int expireTime){
Jedis jedis = null;
Long result = 0L;
try {
jedis = jedisPool.getResource();
result = jedis.rpush(key, values);
if(result > 0){
jedis.expire(key,expireTime);
}
} finally {
if(jedis != null){
jedis.close();
}
}
return result; } /**
* 释放锁
* @param lockKey
*/
public Long releaseLock(String lockKey){
Long result = 0L;
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
result = jedis.del(lockKey);
} finally {
if(jedis != null){
jedis.close();
}
}
return result;
} }

(3)jedisPool配置

可以根据自己情况换成pringboot类配置

<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="3000"></property>
<property name="maxIdle" value="300"></property>
<property name="minIdle" value="10"></property>
<property name="maxWaitMillis" value="15000"></property>
<property name="minEvictableIdleTimeMillis" value="300000"></property>
<property name="numTestsPerEvictionRun" value="3"></property>
<property name="timeBetweenEvictionRunsMillis" value="60000"></property>
<property name="testOnBorrow" value="true"></property>
<property name="testOnReturn" value="true"></property>
<property name="testWhileIdle" value="true"></property>
</bean> <bean id="jedisPool" class="redis.clients.jedis.JedisPool" destroy-method="destroy">
<!-- config -->
<constructor-arg ref="jedisPoolConfig"/>
<!-- host -->
<constructor-arg value="127.0.0.1" type="java.lang.String" />
<!-- port -->
<constructor-arg value="6379" type="int" />
<!-- timeout -->
<constructor-arg value="15000" />
</bean>
<context:component-scan base-package="com.td.yousan.util"/>
</beans>

(4)使用举例

@Resource
private JedisUtil jedisUtil; String lockKey=userId;//锁key
String requestId = UUID.randomUUID().toString();//请求标识
final int EXPIRED_TIME = 300*1000;//redis 数据存储过期时间 //加锁举例
boolean lockResult = jedisUtil.tryGetDistributedLock(lockKey, requestId, EXPIRED_TIME) //放锁举例
booleanr releaseResult =jedisUtil.releaseDistributedLock(lockKey, requestId);

redis分布式锁工具类的更多相关文章

  1. java中redis的分布式锁工具类

    使用方式 try { if(PublicLock.getLock(lockKey)){ //这里写代码逻辑,执行完后需要释放锁 PublicLock.freeLock(lockKey); } } ca ...

  2. redis实现分布式锁工具类 灰常好用

    public interface RedisDistributionLock { /** * 加锁成功,返回加锁时间 * @param lockKey * @param threadName * @r ...

  3. redis实现分布式锁--工具类

    1.引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  4. 面试官问我,Redis分布式锁如何续期?懵了。

    前言 上一篇[面试官问我,使用Dubbo有没有遇到一些坑?我笑了.]之后,又有一位粉丝和我说在面试过程中被虐了.鉴于这位粉丝是之前肥朝的粉丝,而且周一又要开启新一轮的面试,为了回馈他长期以来的支持,所 ...

  5. 面试官再问Redis分布式锁如何续期?这篇文章甩 他一脸

    一.真实案例 二.Redis分布式锁的正确姿势 据肥朝了解,很多同学在用分布式锁时,都是直接百度搜索找一个Redis分布式锁工具类就直接用了.关键是该工具类中还充斥着很多System.out.prin ...

  6. SpringBoot集成Redis分布式锁以及Redis缓存

    https://blog.csdn.net/qq_26525215/article/details/79182687 集成Redis 首先在pom.xml中加入需要的redis依赖和缓存依赖 < ...

  7. Redis分布式锁实战

    什么是分布式锁 在单机部署的情况下,要想保证特定业务在顺序执行,通过JDK提供的synchronized关键字.Semaphore.ReentrantLock,或者我们也可以基于AQS定制化锁.单机部 ...

  8. 以商品超卖为例讲解Redis分布式锁

    本案例主要讲解Redis实现分布式锁的两种实现方式:Jedis实现.Redisson实现.网上关于这方面讲解太多了,Van自认为文笔没他们好,还是用示例代码说明. 一.jedis 实现 该方案只考虑R ...

  9. Redis分布式锁的实现以及工具类

    一.应用场景: 本文应用的场景为在查询数据时,发现数据不存在此时就需要去查询数据库并且更新缓存,此时可能存在高并发的请求同时打在数据库上,而针对这种情况必须要给这些请求加锁,故而采用了分布式锁的方式. ...

随机推荐

  1. hive-issue-inserting-records-to-partitioned-table

    hive-issue-inserting-records-to-partitioned-table Hi Sam, Recently we upgraded our cluster from HDP2 ...

  2. mysql 主从设置

    方法: 1.主服务器建立二进制日志,每产生语句或磁盘变化,写进日志 2.从服务器建立 relaylog日志 3.主服务器授权复制账号 4.从服务器利用复制账号来监听主服务器的日志 5.注意:所以的my ...

  3. Hadoop 操作常见问题解决

    1. 安全模式下不可操作 提示信息: Hadoop "Cannot create directory .Name node is in safe mode." 解决方法: $ ha ...

  4. NeuChar 平台使用及开发教程(三):使用 NeuChar 的菜单服务

    上一篇<NeuChar 平台使用及开发教程(二):设置平台账号>我们已经完成了平台账号的设置,下面就马上来体验一下自定义菜单的设置吧! 进入某个 Neural Cell 的设置界面,在右侧 ...

  5. python3 stack/ queue和deque模块

    '''栈stack 先进后出FILO (first in last out)'''lst = []lst.append("张一山")lst.append("杨紫" ...

  6. Ubuntu 16.04安装Nginx

    在Ubuntu下安装Nginx有以下方法,但是如果想要安装最新版本的就必须下载源码包编译安装. 一.基于APT源安装 sudo apt-get install nginx 安装好的文件位置: /usr ...

  7. [Swift]LeetCode592. 分数加减运算 | Fraction Addition and Subtraction

    Given a string representing an expression of fraction addition and subtraction, you need to return t ...

  8. Json数组转换字符串、字符串转换原数组......

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  9. C# 多线程学习笔记 - 3

    本文主要针对 GKarch 相关文章留作笔记,仅在原文基础上记录了自己的理解与摘抄部分片段. 遵循原作者的 CC 3.0 协议. 如果想要了解更加详细的文章信息内容,请访问下列地址进行学习. 原文章地 ...

  10. asp.net core 系列 8 Razor框架路由(下)

    三.页面路由操作约定 接着上篇讲asp.net core 系列 7 Razor框架路由.在上篇继续第三节 "页面路由操作约定" 的最后一小节 AddPageRoute . 3.3. ...