奇趣闻 > 数码科技 > \

【数据存储】【Redis】高并发下实现分布式锁

原标题:【数据存储】【Redis】高并发下实现分布式锁

大部分互联网公司实现分布式锁原理

/**

* 分布式锁底层实现原理

* @return

*/

@GetMapping("distributedLock")

public Object distributedLock(){

String lockKey = "distributedLockKey";

//给每个线程都设置一个唯一标识,避免出现程序执行的时间超过设置的过期时间,导致其他线程删除了自己的锁

String clientId = UUID.randomUUID().toString();

try {

//添加过期时间保证线程运行到一半的时候,程序崩了,导致缓存中的key一直存在

Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 30, TimeUnit.SECONDS);

if (!result) {

return "error_code";

}

// Todo 实现业务逻辑

redisTemplate.opsForValue().set(TestConstant.KEY_TEST,String.valueOf(System.currentTimeMillis()));

} finally {

//判断是不是自己的线程删除自己的锁

if (clientId.equals(redisTemplate.opsForValue().get(lockKey))) {

redisTemplate.delete(lockKey);

}

}

//Todo 当前代码未实现锁续命功能,锁续命功能:由于程序执行时间可能超过设置缓存中锁的过期时间,导致后续一部分业务未执行,一直被其他线程抢占,需要对锁进行续命,但是由于续命的时间不好确定,这个时候就需要单独开启子线程,定时任务不断的去判断当前锁,还在不在,如果不在了,说明业务已经执行完成了,如果还在,重新设置过期时间,一般而言,定时任务的时间为缓存设置的过期时间三分之一就可以了。

return "end";

}

/**

* 分布式锁底层实现原理

* @return

*/

@GetMapping("distributedLock")

public Object distributedLock(){

String lockKey = "distributedLockKey";

//给每个线程都设置一个唯一标识,避免出现程序执行的时间超过设置的过期时间,导致其他线程删除了自己的锁

String clientId = UUID.randomUUID().toString();

try {

//添加过期时间保证线程运行到一半的时候,程序崩了,导致缓存中的key一直存在

Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 30, TimeUnit.SECONDS);

if (!result) {

return "error_code";

}

// Todo 实现业务逻辑

redisTemplate.opsForValue().set(TestConstant.KEY_TEST,String.valueOf(System.currentTimeMillis()));

} finally {

//判断是不是自己的线程删除自己的锁

if (clientId.equals(redisTemplate.opsForValue().get(lockKey))) {

redisTemplate.delete(lockKey);

}

}

//Todo 当前代码未实现锁续命功能,锁续命功能:由于程序执行时间可能超过设置缓存中锁的过期时间,导致后续一部分业务未执行,一直被其他线程抢占,需要对锁进行续命,但是由于续命的时间不好确定,这个时候就需要单独开启子线程,定时任务不断的去判断当前锁,还在不在,如果不在了,说明业务已经执行完成了,如果还在,重新设置过期时间,一般而言,定时任务的时间为缓存设置的过期时间三分之一就可以了。

return "end";

}

基于redisson实现高并发分布式锁

引入依赖:

org.redisson

redisson

3.6.5

org.redisson

redisson

3.6.5

启动类中注入bean对象:

@Bean

public Redisson redisson() {

// 此为单机模式

Config config = new Config();

config.useSingleServer().setAddress("redis://localhost:6379").setDatabase(0);

return (Redisson) Redisson.create(config);

}

@Bean

public Redisson redisson() {

// 此为单机模式

Config config = new Config();

config.useSingleServer().setAddress("redis://localhost:6379").setDatabase(0);

return (Redisson) Redisson.create(config);

}

实现分布式:

@Autowired

RedisTemplate redisTemplate;

@Autowired

private Redisson redisson;

/**

* 基于redisson实现高并发分布式锁

* @return

*/

@GetMapping("highConcurrencyDistributedLock")

public Object highConcurrencyDistributedLock(){

RLock redissonLock = redisson.getLock(TestConstant.HIGH_CONCURRENCY_DISTRIBUTED_LOCK);

try {

//加锁,实现了key设置,过期时间,锁续命功能

redissonLock.lock(); //redisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 30, TimeUnit.SECONDS);

// Todo 实现业务逻辑

redisTemplate.opsForValue().set(TestConstant.KEY_TEST,String.valueOf(System.currentTimeMillis()));

} finally {

//释放锁

redissonLock.unlock();

}

return redisTemplate.opsForValue().get(TestConstant.KEY_TEST);

}

@Autowired

RedisTemplate redisTemplate;

@Autowired

private Redisson redisson;

/**

* 基于redisson实现高并发分布式锁

* @return

*/

@GetMapping("highConcurrencyDistributedLock")

public Object highConcurrencyDistributedLock(){

RLock redissonLock = redisson.getLock(TestConstant.HIGH_CONCURRENCY_DISTRIBUTED_LOCK);

try {

//加锁,实现了key设置,过期时间,锁续命功能

redissonLock.lock(); //redisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 30, TimeUnit.SECONDS);

// Todo 实现业务逻辑

redisTemplate.opsForValue().set(TestConstant.KEY_TEST,String.valueOf(System.currentTimeMillis()));

} finally {

//释放锁

redissonLock.unlock();

}

return redisTemplate.opsForValue().get(TestConstant.KEY_TEST);

}

显示全文

相关文章