Redis Java Client选型-Jedis Lettuce Redisson
最常用的可重入锁(Reentrant Lock) 先写个单元测试试一下
public class RedisLockTest {
private RedissonClient redissonClient;
//请求的key
private static final String demo ="u001";
//模拟短时间内的并发请求量
private static final int threadNum =5;
@Before
public void init(){
Config config = new Config();
().setAddress("redis://120.78.144.70:6379");
= (config);
(().getName()+"是否存在key"+(demo).isExists());
}
private class UserRequest implements Runnable{
private CountDownLatch cdl;
public UserRequest(CountDownLatch latch){
=latch;
}
@Override
public void run() {
try {
if ((demo).tryLock(0L,-1L, )) {
(().getName()+"获取锁成功");
(5000);
(demo).unlock();
(().getName()+"释放锁成功");
}else{
(().getName()+"获取锁失败"+"是否存在key"+(demo).isExists());
}
}catch (Exception e) {
();
}finally {
//倒计时计数一次
();
}
}
}
@Test
public void testRedissonLock(){
CountDownLatch cdl=new CountDownLatch(threadNum);
Executor executor = (threadNum);
try{
for (int i =0; i< threadNum; i++) {
if(i==2){
//模拟在业务代码没执行完毕时另一个线程获取锁
(1500);
}
(new UserRequest(cdl));
}
//阻塞主线程,等待所有的子线程执行完毕
();
}catch (Exception e){
();
}
}
}
分布式锁的实现分析参考
/p/a8b3473f9c24
比较关注的一个参数一个是过期时间,一个是定时续约过期时间
通过阅读源码知道lesstime参数决定是否续约
private <T> RFuture<Long> tryAcquireAsync(long leaseTime, TimeUnit unit, final long threadId) {
if (leaseTime != -1L) {
return (leaseTime, unit, threadId, RedisCommands.EVAL_LONG);
} else {
RFuture<Long> ttlRemainingFuture = (().getCfg().getLockWatchdogTimeout(), , threadId, RedisCommands.EVAL_LONG);
(new FutureListener<Long>() {
public void operationComplete(Future<Long> future) throws Exception {
if (()) {
Long ttlRemaining = (Long)();
if (ttlRemaining == null) {
(threadId);
}
}
}
});
return ttlRemainingFuture;
}
}
总结一点
if(leaseTime==-1L){
开启自动续期的定时任务,不断重置过期时间为lockWatchdogTimeout
定时任务的频率为lockWatchdogTimeout配置时间的1/3
}else{
不自动续期
设置过期时间为leaseTime
}
所有属性介绍 /articles/551640/
其他锁类型的锁参考
(联锁,红锁,读写锁,信号量,可过期性信号量)
/l1028386804/article/details/73523810