实例代码地址,请前往:https://gitee.com/GuoqingLee/distributed-seckill

redis官方文档地址,请前往:http://www.redis.cn/topics/distlock.html

前言

关于分布式锁的实现,目前主流方案有以下三类:

1、基于数据库的乐观锁;

2、基于redis实现的锁服务;

3、基于zookeeper的实现;

网上关于怎么实现redis的分布式锁,一搜一大把的文章,有写的比较好的,也有明显存在缺陷的,非常容易误导初入这一块的初学者;

而存在的问题,无外乎是setnx()-->expire(),保证不了原子性,容易出现死锁等情况,这里就不在去做解释了;

本文的主旨是如何使用redis官方推荐的redisson实现redis的分布式锁;

一、具体实现:

maven引入需要的jar

 <dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.10.1</version>
</dependency>

配置文件如下

# common spring boot settings

spring.redis.database=
spring.redis.host=
spring.redis.port=
spring.redis.password=
spring.redis.ssl=
spring.redis.timeout=
spring.redis.cluster.nodes=
spring.redis.sentinel.master=
spring.redis.sentinel.nodes=

封装工具类:

 package cn.com.bluemoon.redis.lock;

 import java.util.concurrent.TimeUnit;

 import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; /**
* 基于Redisson的分布式锁实现
* @author Guoqing.Lee
* @date 2019年1月23日 下午4:04:57
*
*/
@Component
public class RedissonDistributedLocker { @Autowired
private RedissonClient redissonClient; /**
* 加锁
* @param lockKey
* @return
*/
public RLock lock(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock();
return lock;
} /**
* 加锁,过期自动释放
* @param lockKey
* @param leaseTime 自动释放锁时间
* @return
*/
public RLock lock(String lockKey, long leaseTime) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock(leaseTime, TimeUnit.SECONDS);
return lock;
} /**
* 加锁,过期自动释放,时间单位传入
* @param lockKey
* @param unit 时间单位
* @param leaseTime 上锁后自动释放时间
* @return
*/
public RLock lock(String lockKey, TimeUnit unit, long leaseTime) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock(leaseTime, unit);
return lock;
} /**
* 尝试获取所
* @param lockKey
* @param unit 时间单位
* @param waitTime 最多等待时间
* @param leaseTime 上锁后自动释放时间
* @return
*/
public boolean tryLock(String lockKey, TimeUnit unit, long waitTime, long leaseTime) {
RLock lock = redissonClient.getLock(lockKey);
try {
return lock.tryLock(waitTime, leaseTime, unit);
} catch (InterruptedException e) {
return false;
}
} /**
* 尝试获取所
* @param lockKey
* @param waitTime 最多等待时间
* @param leaseTime 上锁后自动释放锁时间
* @return
*/
public boolean tryLock(String lockKey, long waitTime, long leaseTime) {
RLock lock = redissonClient.getLock(lockKey);
try {
return lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
} catch (InterruptedException e) {
return false;
}
} /**
* 释放锁
* @param lockKey
*/
public void unlock(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
lock.unlock();
} /**
* 释放锁
* @param lock
*/
public void unlock(RLock lock) {
lock.unlock();
} }

二、使用方式

方式一:

     @Autowired
private RedissonDistributedLocker redissonDistributedLocker; String lockKey = "BM_MARKET_SECKILL_" + stallActivityId;
try {
//超过2S自动释放锁
redissonDistributedLocker.lock(lockKey, 2L);
//业务处理 } finally {
redissonDistributedLocker.unlock(lockKey); //释放锁
}

方案二:

 @Autowired
private RedissonDistributedLocker redissonDistributedLocker; public void test() throws InterruptedException {
final int[] counter = {0}; for (int i= 0; i < 100; i++){ new Thread(new Runnable() { @Override public void run() {
boolean isGetLock = redissonDistributedLocker.tryLock("test0001", 3L, 1L);
if(isGetLock) {
try {
int a = counter[0];
counter[0] = a + 1;
logger.info(a + "");
} finally {
redissonDistributedLocker.unlock("test0001");
}
}
}
}).start(); } // 主线程休眠,等待结果
Thread.sleep(5000);
System.out.println(counter[0]);
logger.info(counter[0] + "");
}

闲话就不多说了,希望能对你有所帮助。

最新文章

  1. .net 实体类与json转换(.net自带类库实现)
  2. java 类之间的关系
  3. jenkins 把包传到远程服务器上
  4. 使用RawSocket进行网络抓包
  5. 在Altium_Designer_PCB_中插入图片的方法
  6. JavaScript判断IE各版本最完美解决方案
  7. mongdb3.0用户验证问题
  8. pap与chap协议
  9. org.apache.hadoop.fs-BlockLocation
  10. Apache Rewrite 中文详解
  11. Apache Kafka系列(二) 命令行工具(CLI)
  12. linux-git
  13. 求集合中选一个数与当前值进行位运算的max
  14. BZOJ2268 : Wormly
  15. git心得
  16. Cortex-M3基础
  17. VC++实现程序重启的方法(转载)
  18. 玩转X-CTR100 l STM32F4 l BMP280气压计传感器
  19. spring-boot + mybatis +pagehelper 使用分页
  20. [转]数据库中Schema(模式)概念的理解

热门文章

  1. 【cl】oracle之Sequence
  2. 线程同步、死锁和通信——Java多线程(二)
  3. 面向对象的三大特性之二——继承(含super的使用)
  4. 用SecureCRT在linux系统下载文件
  5. ubuntu查看文件大小
  6. ASCII和ASCII扩展表
  7. 关于各浏览器下Hack的写法
  8. JS网站图集相册特效
  9. hdu2282 Chocolate 完美匹配 + 拆点
  10. 使用eclipse,对spring boot 进行springloader或者devtool热部署失败处理方法