redission用来做分布式锁比zookeeper更方便,简单。
引入依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>2.10.7</version>
<scope>compile</scope>
</dependency>
配置redission
@Import(SLockAspect.class) //引入AOP配置
@AutoConfigureAfter(RedisAutoConfiguration.class) // 配置Redis
@EnableConfigurationProperties(value = {SLockConfig.class}) //自动注册配置文件
public class RedissionAutoConfig {
@Resource
private SLockConfig sLockConfig;
@Bean(destroyMethod = "shutdown")
@ConditionalOnMissingBean(name = "redission")
public RedissonClient redission() {
Config config = new Config();
config.useSingleServer()
.setPassword(this.sLockConfig.getPassword())
.setAddress(this.sLockConfig.getAddress());
return Redisson.create(config);
}
@Bean
public LockInfoProvider lockInfoProvider() {
return new LockInfoProvider();
}
@Bean
public SLockFactory sLockFactory() {
return new SLockFactory();
}
}
其中 SLockAspect.class 就是一个一个注解,基于AOP切面的,SLockConfig.class就是读入 redission的配置文件
自主义注解 SLock
@Target(value = {ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface SLock {
/**
* 锁名称
*
* @return
*/
String name() default "";
/**
* 锁类型,默认Fair公平锁
*
* @return
*/
LockType lockType() default LockType.FAIR;
/**
* 尝试加锁等待时长,默认 Long.MIN_VALUE
*
* @return
*/
long waitTime() default Long.MIN_VALUE;
/**
* 自动解锁时长,默认 Long.MIN_VALUE
*
* @return
*/
long releaseTime() default Long.MIN_VALUE;
enum LockType {
/**
* 可重入锁
*/
REENTRANT,
/**
* 公平锁
*/
FAIR,
/**
* 读锁
*/
READ,
/**
* 写锁
*/
WRITE,
}
}
测试
@GetMapping("/{id}")
@SLock(name = "BB",waitTime = Long.MAX_VALUE, releaseTime = 5)
public String hello(@PathVariable Long id){
Long counter = redisTemplate.opsForValue().increment("COUNTER", 1);
try {
log.info(id +" locked and begin...");
Thread.sleep(5000); 模拟处理过程 do something.
} catch (Exception ex) {
log.error("Error occurred");
} finally {
log.info(id +" unlocked...");
}
return "lock-" + id ;
}
当多线程测试的时候,下一个线程总会等到上一个线程完成后再继续。