Java中函數(shù)式接口實現(xiàn)分布式鎖
背景
最近使用分布式鎖比較多,發(fā)現(xiàn)大家使用分布式鎖,都各有各的用法,想著用搞一個加鎖模板,方便大家使用,就選擇聲明一個函數(shù)式接口,去實現(xiàn)加鎖的模板
函數(shù)式接口
是一種特殊的接口,只包含一個抽象方法。函數(shù)式接口的目的是為了支持函數(shù)式編程,使開發(fā)者能夠以更簡潔的方式定義單一抽象方法的接口,從而可以使用Lambda表達式來實現(xiàn)這個接口的抽象方法??梢酝ㄟ^lambda表達式進行傳遞,簡單理解就是java8對函數(shù)式編程的一種支持
實戰(zhàn)
我們一般加鎖是這樣,嘗試獲取鎖,失敗則拋異常,成功則執(zhí)行業(yè)務(wù)代碼,每次都要寫一大段邏輯
RLock lock = redissonClient.getLock(lockKey);
try {
if (!lock.tryLock(waitTime, leaseTime, unit)) {
throw new CommonException(ErrorCodeEnum.TRY_LOCK_ERROR).detailMessage("操作頻繁,請稍后再試!");
}
。。。。業(yè)務(wù)代碼
}catch (CommonException commonException) {
} catch (Exception e) {
log.error("LockTemplate >> 獲取鎖異常",e);
} finally {
try {
// 鎖不為空 是否還是鎖定狀態(tài) 當(dāng)前執(zhí)行線程的鎖
if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
}
} catch (Exception e) {
log.error("LockTemplate >> 獲取鎖異常",e);
}
}
}
所以可以采用函數(shù)是接口,定義一套加鎖模板,開發(fā)者就可以只關(guān)注業(yè)務(wù)代碼,而不用去寫一大段加鎖邏輯,
package com.dept.common.template;
import cn.hutool.core.util.StrUtil;
import com.dept.common.enums.ErrorCodeEnum;
import com.dept.common.exception.CommonException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Service
@AllArgsConstructor
@Slf4j
public class LockTemplate {
private RedissonClient redissonClient;
public void templateLock(String prefix,String key,Runnable target,long waitTime, long leaseTime, TimeUnit unit) {
String lockKey = StrUtil.format(prefix,key);
// 判斷是否正在使用
RLock lock = redissonClient.getLock(lockKey);
try {
if (!lock.tryLock(waitTime, leaseTime, unit)) {
throw new CommonException(ErrorCodeEnum.TRY_LOCK_ERROR).detailMessage("操作頻繁,請稍后再試!");
}
// 執(zhí)行業(yè)務(wù)代碼
target.run();
}catch (CommonException e){
throw e;
} catch (Exception e) {
log.error("LockTemplate >> 獲取鎖異常",e);
} finally {
try {
// 鎖不為空 是否還是鎖定狀態(tài) 當(dāng)前執(zhí)行線程的鎖
if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
}
} catch (Exception e) {
log.error("LockTemplate >> 獲取鎖異常",e);
}
}
}
}
重點就是將Runnable做為入?yún)?,Runnable是一個函數(shù)式接口,所以我們可以直接傳入業(yè)務(wù)實現(xiàn),當(dāng)然我們也可以自己定義一個函數(shù)式接口
lockTemplate.templateLock(SystemConstants.STAR_TASK_MINA_ORDER_LOCK, order.getOrderSn(), () -> {
。。。業(yè)務(wù)實現(xiàn)
}, RedisConstants.ONE_SECOND, RedisConstants.TEN_SECOND, TimeUnit.MINUTES);
這樣我們就可以不用去關(guān)注加鎖邏輯,只需要寫自己的業(yè)務(wù)代碼接口
總結(jié)
通過函數(shù)式接口,我們可以定義很多模板代碼,讓開發(fā)者只需要傳入對應(yīng)的業(yè)務(wù)實現(xiàn)即可,TransactionTemplate的execute的方法也是類似的實現(xiàn)
到此這篇關(guān)于Java中函數(shù)式接口實現(xiàn)分布式鎖的文章就介紹到這了,更多相關(guān)Java 分布式鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot使用TraceId進行日志鏈路追蹤的實現(xiàn)步驟
有時候一個業(yè)務(wù)調(diào)用鏈場景,很長,調(diào)了各種各樣的方法,看日志的時候,各個接口的日志穿插,確實讓人頭大,所以為了解決這個問題,本文給大家介紹了SpringBoot使用TraceId進行日志鏈路追蹤的實現(xiàn)步驟,需要的朋友可以參考下2024-11-11
SpringBoot實現(xiàn)攔截Http請求并設(shè)置請求頭
這篇文章主要為大家詳細(xì)介紹了如何使用SpringBoot實現(xiàn)攔截Http請求并設(shè)置請求頭,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2026-01-01

