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 上锁的秒数
* @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("本实例无需执行定时任务");
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实现锁机制。
下方是java代码
@Component
@Slf4j
public class RedisSingleLock {
private final StringRedisTemplate redis;
public SimpleDistributedLock(StringRedisTemplate redis) {
this.redis = redis;
}
//这个方法,可以传入key加锁;多线程调用时,只有1个能获取锁成功,其它线程则会进入循环,不停尝试获取锁
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释放锁,当持有锁的线程执行业务代码完毕后调用,释放这个锁;上方某一个在lock方法中循环尝试获得锁的线程可以获得锁,另外的线程则继续循环等待
public void releaseLock(String key) {
redis.delete(key);
}
//这个方法只尝试获取一次锁,返回获取结果
public boolean tryLock(String key) {
Boolean lockSuccess = redis.opsForValue().setIfAbsent(key, "1", 1, TimeUnit.DAYS);
if (lockSuccess == null) {
throw new IllegalStateException();
}
return lockSuccess;
}
}
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
相关文章
浅谈Java代码的 微信长链转短链接口使用 post 请求封装Json(实例)
下面小编就为大家带来一篇浅谈Java代码的 微信长链转短链接口使用 post 请求封装Json(实例)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧2017-07-07
Java文件处理之使用itextpdf实现excel转pdf
在文件处理中,经常有文件类型转换的使用场景,本文主要介绍了如何使用poi以及itextpdf完成excel转pdf的操作,需要的小伙伴可以参考一下2024-02-02
解析spring-boot-starter-parent简介
本文通过代码的形式给大家介绍了spring-boot-starter-parent的基础知识,需要的朋友可以参考下2018-09-09


最新评论