介紹Redisson
什么是 Redisson?來自于官網上的描述內容如下!
Redisson 是一個在 Redis 的基礎上實現的 Java 駐內存數據網格客戶端(In-Memory Data Grid)。它不僅提供了一系列的 redis 常用數據結構命令服務,還提供了許多分布式服務,例如分布式鎖、分布式對象、分布式集合、分布式遠程服務、分布式調度任務服務等等。
相比于 Jedis、Lettuce 等基于 redis 命令封裝的客戶端,Redisson 提供的功能更加高端和抽象
配置Redisson
引入依賴
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.13.6</version></dependency>
配置客戶端類
@Configuration
public class RedisConfig {@Beanpublic RedissonClient redissonClient(){Config config = new Config();//添加了單機redis地址,也可以使用useClusterServers()添加集群地址config.useSingleServer().setAddress("redis://192.168.2.129:6379").setPassword("linux02");return Redisson.create(config);}
}
?使用Redisson分布式鎖
Long id = UserHolder.getUser().getId();RLock redisLock = redissonClient.getLock("lock:order:" + id);//嘗試獲取鎖boolean tryLock = redisLock.tryLock();//判斷鎖是否獲取成功if (!tryLock){return Result.fail("不允許重復下單");}try {//鎖加到這里,事務提交后才釋放鎖//獲取事務的動態代理對象,需要在啟動類加注解暴漏出對象IVoucherOrderService proxy = (IVoucherOrderService)AopContext.currentProxy();//拿到動態代理對象return proxy.createVoucherOrder(voucherId, voucher);//使用動態代理類的對象,事務可以生效} finally {redisLock.unlock();}
不可重入鎖
在同一個線程中,method1獲取鎖后,調用method2,method2中嘗試獲取鎖,此時鎖已經被method1獲取,則method2獲取鎖失敗,這就是不可重入鎖,前面實現的鎖就是不可重入鎖!
Redisson可重入鎖
????????可重入鎖,從字面來理解,就是可以重復進入的鎖,也叫做遞歸鎖,指的是同一線程外層函數獲得鎖之后,內層遞歸函數仍然有獲取該鎖的代碼,但不受影響。
????????ReentrantLock和synchronized都是可重入鎖。
????????在一個類中,如果synchronized方法1調用了synchronized方法2,方法2是可以正常執行的,這說明synchronized是可重入鎖。否則,在執行方法2想獲取鎖的時候,該鎖已經在執行方法1時獲取了,那么方法2將永遠得不到執行。
?為了實現可重入鎖,redis中使用hash類型不再使用string類型,為什么要使用hash類型,就不得不說到Redisson可重入鎖在redis中的實現原理:
實現原理 :?? ? ??
????????在同一線程中,method1成功獲取鎖后調用method2,method2也嘗試獲取鎖,此時要先判斷method2所在線程和method1所在線程是否是同一線程,若是,則method2也獲取鎖成功,它和method1顯然獲取了同一個鎖,那么該鎖被獲取次數+1,而這個鎖被獲取的次數我們需要記錄,也就是說value不僅要記錄 線程名 還要記錄 鎖被獲取的次數,那么我們就由此采用hash類型更合理!
為什么記錄鎖被獲取的次數?
一個業務的完成可能要多次獲取鎖,如一個業務中執行了method1,method1調用了method2,method2調用了method3,這三個方法都加同一個鎖(可重入鎖),當method3執行完后,并不能立刻釋放method3的鎖,而是鎖被獲取的次數-1,因為鎖是共享的,此時method1和method2還沒執行完不能釋放鎖,那么什么時候釋放鎖?當然是鎖被獲取的次數減為0了,說明此時已經沒有方法獲取鎖,那么可以安全的釋放可重入鎖了。
So鎖被獲取的次數就是我們判斷是否要釋放鎖的依據!