实例代码地址,请前往: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] + "");
}

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

基于redis的分布式锁实现方案--redisson的更多相关文章

  1. 基于redis 实现分布式锁的方案

    在电商项目中,经常有秒杀这样的活动促销,在并发访问下,很容易出现上述问题.如果在库存操作上,加锁就可以避免库存卖超的问题.分布式锁使分布式系统之间同步访问共享资源的一种方式 基于redis实现分布式锁 ...

  2. 基于redis的分布式锁的分析与实践

    ​ 前言:在分布式环境中,我们经常使用锁来进行并发控制,锁可分为乐观锁和悲观锁,基于数据库版本戳的实现是乐观锁,基于redis或zookeeper的实现可认为是悲观锁了.乐观锁和悲观锁最根本的区别在于 ...

  3. 不用找了,基于 Redis 的分布式锁实战来了!

    Java技术栈 www.javastack.cn 优秀的Java技术公众号 作者:菜蚜 my.oschina.net/wnjustdoit/blog/1606215 前言:在分布式环境中,我们经常使用 ...

  4. 基于Redis的分布式锁真的安全吗?

    说明: 我前段时间写了一篇用consul实现分布式锁,感觉理解的也不是很好,直到我看到了这2篇写分布式锁的讨论,真的是很佩服作者严谨的态度, 把这种分布式锁研究的这么透彻,作者这种技术态度真的值得我好 ...

  5. 基于 Redis 的分布式锁

    前言 分布式锁在分布式应用中应用广泛,想要搞懂一个新事物首先得了解它的由来,这样才能更加的理解甚至可以举一反三. 首先谈到分布式锁自然也就联想到分布式应用. 在我们将应用拆分为分布式应用之前的单机系统 ...

  6. 基于redis的分布式锁(转)

    基于redis的分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...

  7. 基于redis的分布式锁(不适合用于生产环境)

    基于redis的分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...

  8. 基于 redis 的分布式锁实现 Distributed locks with Redis debug 排查错误

    小结: 1. 锁的实现方式,按照应用的实现架构,可能会有以下几种类型: 如果处理程序是单进程多线程的,在 python下,就可以使用 threading 模块的 Lock 对象来限制对共享变量的同步访 ...

  9. 基于redis 实现分布式锁(二)

    https://blog.csdn.net/xiaolyuh123/article/details/78551345 分布式锁的解决方式 基于数据库表做乐观锁,用于分布式锁.(适用于小并发) 使用me ...

随机推荐

  1. XTU OJ 1207 Welcome to XTCPC (字符串签到题)

    Problem Description Welcome to XTCPC! XTCPC start today, you are going to choose a slogan to celebra ...

  2. WinForm使用CefSharp内嵌chrome浏览器

    先贴运行图:亲测可用!以图为证! 开始!1.创建winform程序,使用.NET 4.5.2或以上(vs2010最高支持.NET 4.0,我使用的是vs2017).这一步容易忽略,简单的说就是将项目. ...

  3. sikuli+eclipse实例

    设置sikuli环境变量 如果在执行脚本的时候出现以下错误: Getting the VisionProxy.dll: Can not find dependent libraries... 把Sik ...

  4. 问题: Unsupported major.minor version 51.0

    Unsupported major.minor version 51.0 问题原因:外部jar包使用jdk1.7(jdk7)编译,而使用此jar包的工程jdk版本为jdk1.6(jdk6),算是版本不 ...

  5. vmware mac 分辨率设置

    1.安装vmware tool 2.关闭虚拟机,在设置中找到显示器项 3.选中“加速3D图形” 4.在监视器中,选中 指定监视器设置,使用任意分辨率 5.如果没有可用分辨率,手动输入,例如 1680* ...

  6. luogu3386 【模板】 二分图匹配

    基本概念:二分图有两种节点:X节点和Y节点.如果X和Y可以匹配, 则X与Y连着一条边.每个X节点最多只能匹配一个Y节点,同时每个Y节点最多只能匹配一个X节点.最大匹配便是最多的匹配数. 交错路径:交错 ...

  7. Hashlib 用户名密码加密 2.0

    #!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2018/7/10 0008 11:44# @Author : Anthony.Waa# @ ...

  8. canvas的常用api

    canvas 标签 <canvas width="600" height="400" id="canvas"></canv ...

  9. 得到Xml中 元素的值

    <?xml version="1.0" encoding="utf-8" ?><Response service="RouteSer ...

  10. WAMP安装之坑

    Apache安装目录不能有空格 Apache根目录修改后不能直接localhost打开,可以通过改变端口,然后输入 localhost:端口号 打开