分布式锁的几种实现方法:redis实现分布式锁
使用失效的方式实现分布式锁(推荐)
import redis.clients.jedis.Jedis;
/**
* 使用redis实现分布式锁(推荐)
*
*/
public class JedLock {
private static final String LOCK_KEY = "jedis_lock";
private static final int RETRY_TIME = 10 * 1000; //等待锁的时间
private static final int EXPIRE_TIME = 60 * 1000;//锁超时的时间
private boolean locked;
private long lockValue;
public synchronized boolean lock(Jedis jedis){
int retryTime = RETRY_TIME;
try {
while (retryTime > 0) {
lockValue = System.nanoTime();
if ("OK".equalsIgnoreCase(jedis.set(LOCK_KEY, String.valueOf(lockValue), "NX", "PX", EXPIRE_TIME))) {
locked = true;
return locked;
}
retryTime -= 100;
Thread.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public synchronized void unlock(Jedis jedis){
if(locked) {
String currLockVal = jedis.get(LOCK_KEY);
if(currLockVal!=null && Long.valueOf(currLockVal) == lockValue){
jedis.del(LOCK_KEY);
locked = false;
}
}
}
public static void main(String[] args) throws InterruptedException {
Jedis jedis = new Jedis("192.168.75.129", 6379);
JedLock redLock = new JedLock();
if(redLock.lock(jedis)) {
System.out.println(Thread.currentThread().getName() + ": 获得锁!");
Thread.sleep(25000);
System.out.println(Thread.currentThread().getName() + ": 处理完成!");
redLock.unlock(jedis);
System.out.println(Thread.currentThread().getName() + ": 释放锁!");
}else {
System.out.println("get lock fail!!!");
}
}
}
判断锁超时的方式实现分布式锁
import redis.clients.jedis.Jedis;
/**
* 使用redis实现分布式锁
*
*/
public class RedLock {
private static final String LOCK_KEY = "redis_lock";
private static final int RETRY_TIME = 10 * 1000; //等待锁的时间
private static final int EXPIRE_TIME = 60 * 1000;//锁超时的时间
private boolean locked;
private long lockValue;
public synchronized boolean lock(Jedis jedis){
int retryTime = RETRY_TIME;
try {
while (retryTime > 0) {
lockValue = System.currentTimeMillis() + EXPIRE_TIME + 1;//锁到期时间
String lockValueStr = String.valueOf(lockValue);
//判断能否获取锁
if (jedis.setnx(LOCK_KEY, lockValueStr) == 1) {
//成功获取锁
locked = true;
return locked;
}
String currLockVal = jedis.get(LOCK_KEY);
// 判断锁是否已经失效
if (currLockVal != null && Long.valueOf(currLockVal) < System.currentTimeMillis()) {
//锁已经失效,使用命令getset设置最新的过期时间
String oldLockVal = jedis.getSet(LOCK_KEY, lockValueStr);
//判断锁是否已经被抢占
if (oldLockVal != null && oldLockVal.equals(currLockVal)) {
locked = true;
return locked;
}
}
retryTime -= 100;
Thread.sleep(100);
}
}catch (Exception e){
e.printStackTrace();
}
return false;
}
public synchronized void unlock(Jedis jedis){
if(locked) {
String currLockVal = jedis.get(LOCK_KEY);
if(currLockVal != null && Long.valueOf(currLockVal) == lockValue) {
jedis.del(LOCK_KEY);
locked = false;
}
}
}
public static void main(String[] args) throws InterruptedException {
Jedis jedis = new Jedis("192.168.75.129", 6379);
RedLock redLock = new RedLock();
if(redLock.lock(jedis)) {
System.out.println(Thread.currentThread().getName() + ": 获得锁!");
Thread.sleep(150000);
System.out.println(Thread.currentThread().getName() + ": 处理完成!");
redLock.unlock(jedis);
System.out.println(Thread.currentThread().getName() + ": 释放锁!");
}else {
System.out.println("get lock fail!!!");
}
}
}
分布式锁的几种实现方法:redis实现分布式锁的更多相关文章
- Java分布式锁的三种实现方案(redis)
方案一:数据库乐观锁 乐观锁通常实现基于数据版本(version)的记录机制实现的,比如有一张红包表(t_bonus),有一个字段(left_count)记录礼物的剩余个数,用户每领取一个奖品,对应的 ...
- Redis之分布式锁
目录 一.加锁原因 二.原子操作 三.分布式锁 四.分布式锁常见问题 一.加锁原因 在一些比较高并发的业务场景,经常听到通过加锁的方法实现线程安全. 下面简单介绍一下 1.1 加锁方式 数据库锁 数据 ...
- SpringBoot电商项目实战 — Redis实现分布式锁
最近有小伙伴发消息说,在Springboot系列文第二篇,zookeeper是不是漏掉了?关于这个问题,其实我在写第二篇的时候已经考虑过,但基于本次系列文章是实战练习,在项目里你能看到Zookeepe ...
- Redis 中的原子操作(3)-使用Redis实现分布式锁
Redis 中的分布式锁如何使用 分布式锁的使用场景 使用 Redis 来实现分布式锁 使用 set key value px milliseconds nx 实现 SETNX+Lua 实现 使用 R ...
- 聊聊如何用 Redis 实现分布式锁?
作者:小林coding 计算机八股文网站:https://xiaolincoding.com 哈喽,我是小林. 今天跟大家聊聊两个问题: 如何用 Redis 实现分布式锁? Redis 是如何解决集群 ...
- 基于redis 实现分布式锁的方案
在电商项目中,经常有秒杀这样的活动促销,在并发访问下,很容易出现上述问题.如果在库存操作上,加锁就可以避免库存卖超的问题.分布式锁使分布式系统之间同步访问共享资源的一种方式 基于redis实现分布式锁 ...
- asp.net core mvc基于Redis实现分布式锁,C# WebApi接口防止高并发重复请求,分布式锁的接口幂等性实现
使用背景:在使用app或者pc网页时,可能由于网络原因,api接口可能被前端调用一个接口重复2次的情况,但是请求内容是一样的.这样在同一个短暂的时间内,就会有两个相同请求,而程序只希望处理第一个请求, ...
- 程序员修神之路--redis做分布式锁可能不那么简单
菜菜哥,复联四上映了,要不要一起去看看? 又想骗我电影票,对不对? 呵呵,想去看了叫我呀 看来你工作不饱和呀 哪有,这两天我刚基于redis写了一个分布式锁,很简单 不管你基于什么做分布式锁,你觉得很 ...
- nginx+iis+redis+Task.MainForm构建分布式架构 之 (redis存储分布式共享的session及共享session运作流程)
本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,上一篇分享文章制作是在windows上使用的nginx,一般正式发布的时候是在linux来配 ...
随机推荐
- 认识并安装RabbitMQ(以Windows系统为例)
一.初识RabbitMQ 百度百科有这么一句话: MQ是消费-生产者模型的一个典型的代表,一端往消息队列中不断写入消息, 而另一端则可以读取或者订阅队列中的消息. MQ和JMS类似,但不同的是JMS是 ...
- go面试题
1)解释什么是GO? GO是一种开源编程语言,可以轻松构建简单.可靠和高效的软件.程序是从包中构建的,其属性允许有效地管理依赖关系. 2)GO中的语法是什么? GO中的语法遵循Extended Bac ...
- IDEA的小技巧:1.Java代码不被识别2.目录下创建的文件夹所显示样式不是文件夹,而是"包"图标样式的问题
在Idea上面一个正常的代码结构是这个样子的,但是有的时候,比如说当我们直接在一个文件夹中随便的创建的时候就会出现一些问题,比如说想让某个地方为代码目录,某个地方为资源目录的时候,直接的创建目录是不成 ...
- MQTT 连接服务端失败,报错客户机未连接(32104)
和同事协同开发项目,在启动项目时偶尔报错连接不到MQTT 服务器. 原因是两个人开发同一个项目,连接MQTT时配置的 client-id 相同,在使用一个client-id连接到MQTT服务器后,再使 ...
- koa 基础(十八)es6中的类、静态方法、继承
1.app.js /** * es6中的类.静态方法.继承 */ // 定义Person类 class Person { constructor(name, age) { /*类的构造函数,实例化的时 ...
- 【.net core 0基础】创建你的第一个.net core应用
1.下载.NET core相应的SDK,https://dotnet.microsoft.com/download 2.安装完成后,打开命令提示符,输入命令 dotnet,检查是否正确安装,如果命令能 ...
- 代码实现:键盘录入一个int类型的整数,对其求二进制表现形式
package com.loaderman.test; import java.math.BigDecimal; import java.math.BigInteger; import java.ut ...
- Helm chart仓库官方仓库不能使用解决方法
Helm chart仓库官方仓库不能使用解决方法 k8s中的官方helm chart仓库在国内可能使用不了,但是我们又需要使用,这里推荐几个方法. 使用其他的chart仓库 微软的chart仓库 ht ...
- JAVA多线程程序ProgressBar2
JAVA多线程程序ProgressBar2 题目简介: 思路分析:与上一篇:JAVA多线程程序ProgressBar类似,本篇避免过于冗杂,所以在此没有给出. 实验代码: import java.aw ...
- go 基础 处理异常
package main import "fmt" func main() { dosomething() } func dosomething(){ defer func() { ...