Redis 整合Redis分布式锁
1. 分布式锁
A. Spring Integration提供多种方式实现分布式锁:Redis、Zookeeper和JDBC等;
B. Spring Integration分布式锁优点是:可重入且防死锁;
C. 应用场景:多实例部署,同时只能一个服务获取锁。
2. Maven依赖
<!-- redis API -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-redis</artifactId>
</dependency>
3. 分布式锁配置
package com.ruhuanxingyun.redis.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.integration.redis.util.RedisLockRegistry;
/**
* @description: 分布式锁配置
* @author: ruphie
* @date: Create in 2020/11/24 21:22
* @company: ruhuanxingyun
*/
@Configuration
public class RedisLockConfig {
@Bean(destroyMethod = "destroy")
public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) {
return new RedisLockRegistry(redisConnectionFactory, "rhxy");
}
}
4. 示例代码
package com.ruhuanxingyun.redis.controller;
import com.ruhuanxingyun.redis.service.RedisLockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @description: Redis分布式锁 控制层
* @author: ruphie
* @date: Create in 2020/11/24 21:25
* @company: ruhuanxingyun
*/
@RestController
@RequestMapping("/api/redis")
public class RedisLockController {
private static final String LOCK_KEY = "cs";
@Autowired
private RedisLockService redisLockService;
@RequestMapping("/lock")
public void lock() {
for (int i = 0; i < 5; i++) {
new Thread(() -> {
redisLockService.lock(LOCK_KEY);
System.out.println(String.format("线程名%s获取锁", Thread.currentThread().getName()));
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
redisLockService.unlock(LOCK_KEY);
System.out.println(String.format("线程名%s释放锁", Thread.currentThread().getName()));
}).start();
}
}
}
package com.ruhuanxingyun.redis.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
/**
* @description: Redis分布式锁 服务层
* @author: ruphie
* @date: Create in 2020/11/24 21:26
* @company: ruhuanxingyun
*/
@Service
public class RedisLockService {
private static final long DEFAULT_EXPIRE_UNUSED = 60000L;
@Autowired
private RedisLockRegistry redisLockRegistry;
/**
* 获取锁,如果锁不可用则线程一直等待
*
* @param lockKey 锁键名
*/
public void lock(String lockKey) {
Lock lock = redisLockRegistry.obtain(lockKey);
lock.lock();
}
/**
* 尝试获取锁,获取失败直接返回false
*
* @param lockKey 锁键名
* @return 是否获取锁
*/
public boolean tryLock(String lockKey) {
Lock lock = redisLockRegistry.obtain(lockKey);
return lock.tryLock();
}
/**
* 可超时获取锁,指定超时时间结束返回false
*
* @param lockKey 锁键名
* @param seconds 超时时间
* @return 是否获取锁
*/
public boolean tryLock(String lockKey, long seconds) {
Lock lock = redisLockRegistry.obtain(lockKey);
try {
return lock.tryLock(seconds, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
}
/**
* 释放锁
*
* @param lockKey 锁键名
*/
public void unlock(String lockKey) {
Lock lock = redisLockRegistry.obtain(lockKey);
lock.unlock();
redisLockRegistry.expireUnusedOlderThan(DEFAULT_EXPIRE_UNUSED);
}
}
5. 结果展示
可参考:分布式锁的实现与原理解析