java如何使用redis加鎖
更新時間:2023年01月09日 16:54:26 作者:KLOCIC
這篇文章主要介紹了java如何使用redis加鎖問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
java使用redis加鎖
編寫LockUtil工具類
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.stereotype.Service;
?
/**
?* LockUtil <br>
?*
?*/
@Service
public class LockUtil {
?
? ? @Autowired
? ? private RedisTemplate redisTemplate;
?
? ? @Autowired
? ? private StringRedisTemplate stringRedisTemplate;
?
? ? /**
? ? ?* @param lockKey 上鎖的key
? ? ?* @param lockSeconds 上鎖的秒數(shù)
? ? ?* @return
? ? ?*/
? ? public boolean lock(String lockKey, int lockSeconds) {
? ? ? ? return (Boolean) redisTemplate.execute((RedisCallback) connection -> {
? ? ? ? ? ? byte[] key = lockKey.getBytes();
? ? ? ? ? ? Boolean set = connection.set(key, key, Expiration.seconds(lockSeconds), SetOption.SET_IF_ABSENT);
? ? ? ? ? ? if (set == null) {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? return set;
? ? ? ? });
? ? }
?
? ? public boolean isLock(String lockKey) {
? ? ? ? return stringRedisTemplate.opsForValue().get(lockKey)!=null;
? ? }
?
?
? ? public boolean clearLock(String lockKey){
? ? ? ?return redisTemplate.delete(lockKey);
? ? }
}使用鎖
public abstract class AbstractTask {
?
? ? @Autowired
? ? private LockUtil lockUtil;
?
? ? /**
? ? ?* 獲取redis鎖的key
? ? ?*
? ? ?* @return
? ? ?*/
? ? protected abstract String getLockKey();
?
? ? protected boolean lock() {
? ? ? ? return lockUtil.lock(getLockKey(), 120);
? ? }
?
? ? protected boolean lockManual() {
? ? ? ? return lockUtil.lock(getLockKey(), 299);
? ? }
?
? ? protected boolean clearLock() {
? ? ? ? return lockUtil.clearLock(getLockKey());
? ? }
}@Component
@Slf4j
@RefreshScope
public class FileCapacityCountTask extends AbstractTask{
? ? @Autowired
? ? private FileCapacityCountService fileCapacityCountService;
? ?
?
? ? @Scheduled(cron = "${batch.verification.schedule.capacity}")
? ? public void task(){
? ? ? ? if (!lock()) {
? ? ? ? ? ? log.info("本實例無需執(zhí)行定時任務(wù)");
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? fileCapacityCountService.fileCapacityCountTask();
? ? }
?
? ? @Override
? ? protected String getLockKey() {
? ? ? ? String today = DateUtil.formatDate(new Date());
? ? ? ? return FileCapacityCountTask.class.getSimpleName() + CommonConstant.APPLICATION_NAME + today;
? ? }
}redis鎖用法java代碼
由于redis是串行的,所以可以用redis實現(xiàn)鎖機制。
下方是java代碼
@Component
@Slf4j
public class RedisSingleLock {
private final StringRedisTemplate redis;
public SimpleDistributedLock(StringRedisTemplate redis) {
this.redis = redis;
}
//這個方法,可以傳入key加鎖;多線程調(diào)用時,只有1個能獲取鎖成功,其它線程則會進入循環(huán),不停嘗試獲取鎖
public void lock(String key) {
do {
Boolean lockSuccess = redis.opsForValue().setIfAbsent(key, "1", 1, TimeUnit.DAYS);
if (lockSuccess == null) {
throw new IllegalStateException();
}
if (!lockSuccess) {
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
log.error(e.getMessage(), e);
}
} else {
break;
}
} while (true);
}
//這個方法,傳入key釋放鎖,當(dāng)持有鎖的線程執(zhí)行業(yè)務(wù)代碼完畢后調(diào)用,釋放這個鎖;上方某一個在lock方法中循環(huán)嘗試獲得鎖的線程可以獲得鎖,另外的線程則繼續(xù)循環(huán)等待
public void releaseLock(String key) {
redis.delete(key);
}
//這個方法只嘗試獲取一次鎖,返回獲取結(jié)果
public boolean tryLock(String key) {
Boolean lockSuccess = redis.opsForValue().setIfAbsent(key, "1", 1, TimeUnit.DAYS);
if (lockSuccess == null) {
throw new IllegalStateException();
}
return lockSuccess;
}
}
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot項目如何設(shè)置session的過期時間
這篇文章主要介紹了springboot項目如何設(shè)置session的過期時間,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01
SpringBoot Mybatis Plus公共字段自動填充功能
這篇文章主要介紹了SpringBoot Mybatis Plus公共字段自動填充功能的相關(guān)資料,需要的朋友可以參考下2017-04-04
java.util.concurrent.ExecutionException 問題解決方法
這篇文章主要介紹了java.util.concurrent.ExecutionException 問題解決方法的相關(guān)資料,需要的朋友可以參考下2016-11-11
springboot讀取nacos配置文件的實現(xiàn)
SpringBoot注冊服務(wù)到Nacos上,由Nacos來做服務(wù)的管理,本文主要介紹了springboot讀取nacos配置文件的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05
Hibernate連接三種數(shù)據(jù)庫的配置文件
今天小編就為大家分享一篇關(guān)于Hibernate連接三種數(shù)據(jù)庫的配置文件,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03

