1. 调用分布式锁的时候, 代码有点繁琐, 每次调用都要写这么一套, 如下
1RLock lock = redissonClient.getLock("lock-1"); 2try { 3 boolean tryLock = lock.tryLock(1, 5, TimeUnit.SECONDS); 4 if(tryLock) { 5 System.out.println("******************** Business ********************"); 6 } 7} catch (InterruptedException e) { 8 e.printStackTrace(); 9} finally { 10 if(lock.isHeldByCurrentThread()) { 11 lock.unlock(); 12 } 13}
2. 封装一个模板类 RedissonLockTemplate 用来调用锁, 封装一个回调类 TryLockCallback 用来包住执行的业务代码
1public interface TryLockCallback<T> { 2 3 T doBusiness(); 4 5} 6 7public class RedissonLockTemplate { 8 private Logger logger = LoggerFactory.getLogger(getClass()); 9 10 private RedissonClient redissonClient; 11 12 public RedissonLockTemplate(RedissonClient redissonClient) { 13 this.redissonClient = redissonClient; 14 } 15 16 public <T> T tryLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit, TryLockCallback<T> action) { 17 RLock lock = redissonClient.getLock(lockKey); 18 T result = null; 19 try { 20 boolean tryLock = lock.tryLock(waitTime, leaseTime, unit); 21 if(tryLock) { 22 result = action.doBusiness(); 23 } 24 } catch (InterruptedException e) { 25 logger.error("{} 锁发生中断异常!", lockKey, e); 26 } finally { 27 if(lock.isHeldByCurrentThread()) { 28 lock.unlock(); 29 } 30 } 31 return result; 32 } 33}
3. 在 SpringBoot 项目中使用
1@SpringBootConfiguration 2public class RedissonConfig { 3 4 @Value("${spring.redis.host}") 5 private String redisHost; 6 @Value("${spring.redis.port}") 7 private String redisPort; 8 9 10 @Bean 11 public RedissonClient redissonClient() { 12 Config config = new Config(); 13// config.useSingleServer().setAddress("redis://127.0.0.1:6379"); 14 config.useSingleServer().setAddress("redis://" + redisHost + ":" + redisPort); 15 return Redisson.create(config); 16 } 17 18 @Bean 19 public RedissonLockTemplate redissonLockTemplate() { 20 RedissonLockTemplate redissonLockTemplate = new RedissonLockTemplate(redissonClient()); 21 return redissonLockTemplate; 22 } 23} 24 25@Autowired 26private RedissonLockTemplate redissonLockTemplate; 27 28 29@RequestMapping("/test") 30@ResponseBody 31public Integer test() { 32 Integer result = redissonLockTemplate.tryLock("lock-1", 1, 5, TimeUnit.SECONDS, new TryLockCallback<Integer>() { 33 @Override 34 public Integer doBusiness() { 35 // 业务代码写在这里 36 System.out.println("************** doBusiness *************"); 37 return 0; 38 } 39 }); 40 return result; 41}
大家看, 是不是简洁了很多.....