(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. MySQL 中 having 和 where 的区别

    区别一: where 是数据从磁盘读入内存时候一条一条判断的 having 是将所有数据读入内存,在分组统计前,根据having的条件再将不符合条件的数据删除 区别二: having 子句可以使用字段 ...

  2. 二、油泼面(Oil spill noodle)

    油泼面 油泼面是陕西传统的特色面食之一,起源于周代,并以咸阳油泼面最为著名,有鲜香味.酸辣味.香辣味. 油泼面是一种很普通的面食制作方法,将手工制作的面条在开水中煮熟后捞在碗里,将葱花碎.花椒粉.盐等 ...

  3. Mysql 创建及导入表

    连接数据库 打开命令行输入mysql -uroot -p 进行数据库连接 创建并访问数据库 CREATE DATABASE test: //创建数据库test SHOW DATABSAES; //查看 ...

  4. 封装一个 员工类 使用preparedStatement 查询数据 (1)

    创建员工类  自动生成get set 方法 package cn.hph; public class emp { //定义表中的属性 private int id; private String en ...

  5. Linux常用服务器搭建

    1.Linux常用服务器构建-ftp服务器 ftp服务器 FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”. 用于Internet上的控制文件 ...

  6. Java synchronized和 Lock 的区别与用法

    在分布式开发中,锁是线程控制的重要途径.Java为此也提供了2种锁机制,synchronized和lock.做为Java爱好者,自然少不了对比一下这2种机制,也能从中学到些分布式开发需要注意的地方.  ...

  7. [Swift]LeetCode73. 矩阵置零 | Set Matrix Zeroes

    Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place. Exampl ...

  8. [Swift]LeetCode594. 最长和谐子序列 | Longest Harmonious Subsequence

    We define a harmonious array is an array where the difference between its maximum value and its mini ...

  9. [Swift]LeetCode722. 删除注释 | Remove Comments

    Given a C++ program, remove comments from it. The program source is an array where source[i] is the  ...

  10. [Swift]LeetCode779. 第K个语法符号 | K-th Symbol in Grammar

    On the first row, we write a 0. Now in every subsequent row, we look at the previous row and replace ...