Redis实现分布式锁释放锁
生活随笔
收集整理的這篇文章主要介紹了
Redis实现分布式锁释放锁
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
package com.learn;//什么線程安全問題 在同一個jvm中,多個線程共享同一個全局變量做寫的操作的時候,可能會收到其他線程的干擾。
class ThreadDemo implements Runnable {// synchronized 至適合于單個jvmprivate static int count;public synchronized void run() {count();}private synchronized void count() {try {Thread.sleep(15);} catch (Exception e) {// TODO: handle exception}count++;System.out.println(Thread.currentThread().getName() + ",count:" + count);}
}public class Test001 {public static void main(String[] args) {ThreadDemo threadDemo = new ThreadDemo();for (int i = 0; i < 100; i++) {Thread thread = new Thread(threadDemo);thread.start();}}
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.learn</groupId><artifactId>redis_lock</artifactId><version>0.0.1-SNAPSHOT</version><dependencies><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</version></dependency></dependencies></project>
package com.learn;import java.util.UUID;import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;public class LockRedis {// redis線程池private JedisPool jedisPool;// 同時在redis上創(chuàng)建相同的一個key 相同key 名稱private String redislockKey = "redis_lock";public LockRedis(JedisPool jedisPool) {this.jedisPool = jedisPool;}// redis 以key (redislockKey) 和value(隨機不能夠重復數(shù)字 鎖的id)方式進行存儲// redis實現(xiàn)分布式鎖 有兩個超時 時間問題/*** 兩個超時時間含義:<br>* 1.在獲取鎖之前的超時時間----在嘗試獲取鎖的時候,如果在規(guī)定的時間內(nèi)還沒有獲取鎖,直接放棄。<br>* 2.在獲取鎖之后的超時時間---當獲取鎖成功之后,對應的key 有對應有效期,對應的key 在規(guī)定時間內(nèi)進行失效*//*** acquireTimeout* * @param acquireTimeout* 在獲取鎖之前的超時時間* @param timeOut* 在獲取鎖之后的超時時間*/// 基于redis實現(xiàn)分布式鎖代碼思路 核心方法 獲取鎖 、釋放鎖public String getRedisLock(Long acquireTimeout, Long timeOut) {Jedis conn = null;try {// 1.建立redis連接conn = jedisPool.getResource();// 2.定義 redis 對應key 的value值( uuid) 作用 釋放鎖 隨機生成valueString identifierValue = UUID.randomUUID().toString();// 3.定義在獲取鎖之后的超時時間int expireLock = (int) (timeOut / 1000);// 以秒為單位// 4.定義在獲取鎖之前的超時時間// 5.使用循環(huán)機制 如果沒有獲取到鎖,要在規(guī)定acquireTimeout時間 保證重復進行嘗試獲取鎖(樂觀鎖)// 使用循環(huán)方式重試的獲取鎖Long endTime = System.currentTimeMillis() + acquireTimeout;while (System.currentTimeMillis() < endTime) {// 獲取鎖// 6.使用setnx命令插入對應的redislockKey ,如果返回為1 成功獲取鎖if (conn.setnx(redislockKey, identifierValue) == 1) {// 設置對應key的有效期conn.expire(redislockKey, expireLock);return identifierValue;}// 為什么獲取鎖之后,還要設置鎖的超時時間 目的是為了防止死鎖// zookeeper實現(xiàn)分布式鎖通過什么方式 防止死鎖 設置session 有效期}} catch (Exception e) {e.printStackTrace();} finally {if (conn != null) {conn.close();}}return null;}// 如果直接使用 conn.del(redislockKey); 保證對應是自己的創(chuàng)建redislockKey 刪除對應自己的。// 釋放redis鎖public void unRedisLock(String identifierValue) {Jedis conn = null;// 1.建立redis連接conn = jedisPool.getResource();try {// 如果該鎖的id 等于identifierValue 是同一把鎖情況才可以刪除if (conn.get(redislockKey).equals(identifierValue)) {System.out.println("釋放鎖..." + Thread.currentThread().getName() + ",identifierValue:" + identifierValue);conn.del(redislockKey);}} catch (Exception e) {} finally {if (conn != null) {conn.close();}}// 釋放鎖有兩種 key自動有有效期// 整個程序執(zhí)行完畢情況下,刪除對應key}
}
package com.learn;import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;public class LockService {private static JedisPool pool = null;static {JedisPoolConfig config = new JedisPoolConfig();// 設置最大連接數(shù)config.setMaxTotal(200);// 設置最大空閑數(shù)config.setMaxIdle(8);// 設置最大等待時間config.setMaxWaitMillis(1000 * 100);// 在borrow一個jedis實例時,是否需要驗證,若為true,則所有jedis實例均是可用的config.setTestOnBorrow(true);pool = new JedisPool(config, "localhost", 6379, 3000, "123456");}private LockRedis lockRedis = new LockRedis(pool);// 演示redis實現(xiàn)分布式鎖public void seckill() {// 1.獲取鎖String identifierValue = lockRedis.getRedisLock(5000l, 5000l);if (identifierValue == null) {System.out.println(Thread.currentThread().getName() + ",獲取鎖失敗,原因因為獲取鎖時間超時...");return;}System.out.println(Thread.currentThread().getName() + ",獲取鎖成功,鎖的id:" + identifierValue + ",正常執(zhí)行業(yè)務了邏輯");// 2.釋放鎖lockRedis.unRedisLock(identifierValue);}
}
package com.learn;public class ThreadRedis extends Thread {private LockService lockService;public ThreadRedis(LockService lockService) {this.lockService = lockService;}@Overridepublic void run() {lockService.seckill();}}
package com.learn;public class Test002 {public static void main(String[] args) {LockService lockService = new LockService();for (int i = 0; i < 50; i++) {new ThreadRedis(lockService).start();}}}
?
總結(jié)
以上是生活随笔為你收集整理的Redis实现分布式锁释放锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis实现分布式锁原理SetNx命令
- 下一篇: Redis与Zookeeper实现分布式