redis分布式锁工具类
(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分布式锁工具类的更多相关文章
- java中redis的分布式锁工具类
使用方式 try { if(PublicLock.getLock(lockKey)){ //这里写代码逻辑,执行完后需要释放锁 PublicLock.freeLock(lockKey); } } ca ...
- redis实现分布式锁工具类 灰常好用
public interface RedisDistributionLock { /** * 加锁成功,返回加锁时间 * @param lockKey * @param threadName * @r ...
- redis实现分布式锁--工具类
1.引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- 面试官问我,Redis分布式锁如何续期?懵了。
前言 上一篇[面试官问我,使用Dubbo有没有遇到一些坑?我笑了.]之后,又有一位粉丝和我说在面试过程中被虐了.鉴于这位粉丝是之前肥朝的粉丝,而且周一又要开启新一轮的面试,为了回馈他长期以来的支持,所 ...
- 面试官再问Redis分布式锁如何续期?这篇文章甩 他一脸
一.真实案例 二.Redis分布式锁的正确姿势 据肥朝了解,很多同学在用分布式锁时,都是直接百度搜索找一个Redis分布式锁工具类就直接用了.关键是该工具类中还充斥着很多System.out.prin ...
- SpringBoot集成Redis分布式锁以及Redis缓存
https://blog.csdn.net/qq_26525215/article/details/79182687 集成Redis 首先在pom.xml中加入需要的redis依赖和缓存依赖 < ...
- Redis分布式锁实战
什么是分布式锁 在单机部署的情况下,要想保证特定业务在顺序执行,通过JDK提供的synchronized关键字.Semaphore.ReentrantLock,或者我们也可以基于AQS定制化锁.单机部 ...
- 以商品超卖为例讲解Redis分布式锁
本案例主要讲解Redis实现分布式锁的两种实现方式:Jedis实现.Redisson实现.网上关于这方面讲解太多了,Van自认为文笔没他们好,还是用示例代码说明. 一.jedis 实现 该方案只考虑R ...
- Redis分布式锁的实现以及工具类
一.应用场景: 本文应用的场景为在查询数据时,发现数据不存在此时就需要去查询数据库并且更新缓存,此时可能存在高并发的请求同时打在数据库上,而针对这种情况必须要给这些请求加锁,故而采用了分布式锁的方式. ...
随机推荐
- LSI IBM服务器阵列卡操作经历
说明:因为服务器的一个磁盘坏了,因为没有经验不敢操作.正好有一台撤下来的相同服务器,所以查找了各种教程,研究了一下各种操作.记录在这里,防止忘记.一.概念说明raid(自己百度)阵列卡组(group) ...
- Conda命令指标
一.Conda相关指令 # 查看当前环境下已安装的包 conda list # 查看某个指定环境的已安装包 conda list -n tensorflow # 查找package信息 conda s ...
- Mesos源码分析(7): Mesos-Slave的启动
Mesos-Slave的启动是从src/slave/main.cpp中的main函数开始的. 看过了Mesos-Master的启动过程,Mesos-Slave的启动没有那么复杂了. 1. ...
- Vue 学习笔记 -- inline-template
简书 更方便的使用私有子组件 定义一个私有子组件时,如果子组件的template过长会使得代码非常难以阅读 这时可以使用内联模版 但是如果写成这样 为毛用要子组件呢?
- 在Windows、Mac和 Linux系统中安装Python与 PyCharm
“工欲善其事,必先利其器”,本文介绍 Python环境的安装和 Python的集成开发环境(IDE) PyCharn的安装. 一.Python安装( Windows.Mac和 Linux) 当前主 ...
- the python challenge闯关记录(0-8)
0 第零关 2**38 = 274877906944 下一关的url:http://www.pythonchallenge.com/pc/def/274877906944.html 1 第一关 移位计 ...
- RAC集群数据库连库代码示例(jdbc thin方式,非oci)
1.RAC集群数据库连库代码示例(jdbc thin方式,非oci):jdbc.driverClassName=oracle.jdbc.driver.OracleDriverjdbc.url=jdbc ...
- solr索引报错(java.lang.OutOfMemoryError:GC overhead limit exceeded)
配置文件修改如下: <dataSource driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3 ...
- 使用ML.NET实现情感分析[新手篇]
在发出<.NET Core玩转机器学习>和<使用ML.NET预测纽约出租车费>两文后,相信读者朋友们即使在不明就里的情况下,也能按照内容顺利跑完代码运行出结果,对使用.NET ...
- Python爬虫入门教程 29-100 手机APP数据抓取 pyspider
1. 手机APP数据----写在前面 继续练习pyspider的使用,最近搜索了一些这个框架的一些使用技巧,发现文档竟然挺难理解的,不过使用起来暂时没有障碍,估摸着,要在写个5篇左右关于这个框架的教程 ...