当前位置:网站首页>学习redis实现分布式锁—–自己的一个理解
学习redis实现分布式锁—–自己的一个理解
2022-06-30 11:06:00 【全栈程序员站长】
一、导入maven依赖 <!– 操作redis的java客户端jedis –> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> 二、代码实现 import java.util.UUID;
import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool;
/** * 分布式锁的思想:多个服务器集群下,只允许其中一个jvm进行操作 * redis实现分布式锁的思路: * * 获取锁:在多个jvm情况下,redis实现分布式锁通过setnx方法创建同一个key , * 这个key是唯一不重复,如果存入成功返回1获取锁,存入失败返回0,value使用一个唯一不重复的随机数作为线程的ID。 * * 释放锁:为了保证线程获取的锁,于释放的锁是同一个,在删除reids的key的时候,要对线程ID进行判断,是同一个ID才进行删除 * * 如何防止死锁 * 1.设置一个获取锁之前的一个时间段,线程如果在这个时间段还没有获取到锁,那么线程就放弃获取锁,返回null * 2.还要设置另一个时间段,就是线程获取到锁之后,对key设置有效时间,过了这个是时间段,key自动删除 ,释放锁 返回线程ID * * @author zxlovey * */ public class LockRedis { // jedis线程池 private JedisPool jedisPool;
public LockRedis(JedisPool jedisPool) { this.jedisPool = jedisPool; }
private String reidsKey = “redis_key”;
// 获取锁 /** * * @param acquireTimeout * 获取锁之前的一个时间段 * @param timeOut * 线程获取到锁之后,对key设置有效时间 一般以秒为单位 */ public String getLockRedis(Long acquireTimeout, Long timeOut) { Jedis conn = null; try { // 获取到jedis conn = jedisPool.getResource();
Long endTime = System.currentTimeMillis() + acquireTimeout; int expireLock = (int) (timeOut / 1000);
String identifierValue = UUID.randomUUID().toString();
while (System.currentTimeMillis() < endTime) { if (conn.setnx(reidsKey, identifierValue) == 1) { // 获取锁 设置有效时间 conn.expire(reidsKey, expireLock); // 返回value,这个value作为线程id 释放锁的时候需要判断删除的key 和获取的锁是同一个 return identifierValue; } }
} catch (Exception e) { // TODO: handle exception } finally { if (conn != null) { conn.close(); } }
return null; }
// 释放锁 /** * * @param identifierValue * 锁的ID,就是key 对应的value */ public void unLockRedis(String identifierValue) { Jedis conn = null; try { conn = jedisPool.getResource();
if (conn.get(reidsKey).equals(identifierValue)) { // 获取的key的value相同,说明是同一个线程的锁资源 // 删除key conn.del(reidsKey); System.out.println(“释放锁成功:” + Thread.currentThread().getName() + “—锁的ID:” + identifierValue); }
} catch (Exception e) {
} finally { if (conn != null) { conn.close(); } } }
}
import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig;
public class LockServer { private static JedisPool pool = null;
static { JedisPoolConfig config = new JedisPoolConfig(); // 设置最大连接数 config.setMaxTotal(200); // 设置最大空闲数 config.setMaxIdle(8); // 设置最大等待时间 config.setMaxWaitMillis(1000 * 100); // 在borrow一个jedis实例时,是否需要验证,若为true,则所有jedis实例均是可用的 config.setTestOnBorrow(true); pool = new JedisPool(config, “127.0.0.1”, 6379, 3000); } private LockRedis lockRedis = new LockRedis(pool); //演示redis实现分布式锁 public void seckill() { //1.获取到锁 String identifierValue = lockRedis.getLockRedis(1000L, 1000L); if(identifierValue == null){ System.out.println(“获取锁失败:”+Thread.currentThread().getName()+”;失败原因是获取锁的时间超时”); return; } System.out.println(“获取锁成功:”+Thread.currentThread().getName()+”—锁的ID:”+identifierValue); //2.释放锁 lockRedis.unLockRedis(identifierValue); } }
public class ThreadLock extends Thread{ private LockServer lockServer; public ThreadLock(LockServer lockServer) { this.lockServer = lockServer; } @Override public void run() { lockServer.seckill(); } }
public class Test001 { public static void main(String[] args) { LockServer lockServer = new LockServer(); for (int i = 0; i < 500; i++) { ThreadLock tl = new ThreadLock(lockServer); tl.start(); } } }
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/100803.html原文链接:https://javaforall.cn
边栏推荐
- 100 important knowledge points that SQL must master: using stored procedures
- Flutter 从零开始 008 表单
- Understanding society at the age of 14 - reading notes on "happiness at work"
- 【leetcode 239】滑动窗口
- R语言去重操作unique duplicate filter
- Flutter start from scratch 008 form
- 60 个神级 VS Code 插件!!
- Problems and solutions in pyinstall packaging for pychart project
- "New digital technology" completed tens of millions of yuan of a + round financing and built an integrated intelligent database cloud management platform
- QT embeds the sub QT program window into the current program
猜你喜欢

The life, working principle and application of electrochemical oxygen sensor

国内首批!阿里云云原生数据湖产品通过信通院评测认证

科普达人丨漫画图解什么是eRDMA?

中移OneOS开发板学习入门

Multiparty cardinality testing for threshold private set-2021: Interpretation

Discussion on the essence of "FPGA mining" from open source projects

Qualcomm released the "magic mirror" of the Internet of things case set, and digital agriculture has become a reality

启明星辰集团运维安全网关(堡垒机)再次夺得榜首!

Dameng data rushes to the scientific innovation board, or becomes the "first share of domestic database" in the A-share market

dplyr 中的filter报错:Can‘t transform a data frame with duplicate names
随机推荐
promise async和await的方法与使用
Line generation (Gauss elimination method, linear basis)
Is the golden cycle of domestic databases coming?
SQL必需掌握的100个重要知识点:联结表
EMC-浪涌
Introduction to China Mobile oneos development board
Object mapping - mapping Mapster
Le talent scientifique 丨 dessins animés qu'est - ce qu'erdma?
[IC5000 tutorial] - 01- use daqdea graphical debug to debug C code
Qt嵌入子Qt程序窗口到当前程序
R language view version R package view version
Dameng data rushes to the scientific innovation board, or becomes the "first share of domestic database" in the A-share market
Set up your own website (13)
What is erdma as illustrated by Coptic cartoon?
100 important knowledge points that SQL must master: Combined Query
The latest collection of arouter problems
[applet practice series] Introduction to the registration life cycle of the applet framework page
关于IP定位查询接口的测评Ⅲ
孔松(信通院)-数字化时代云安全能力建设及趋势
datax json说明