- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-redisartifactId>
- <version>1.4.7.RELEASEversion>
- dependency>
-
- <dependency>
- <groupId>org.redissongroupId>
- <artifactId>redissonartifactId>
- <version>3.17.4version>
- dependency>
下面代码有单个redis配置和redis集群配置,需要修改成自己的redis地址
- @Configuration
- public class RedissonConfig {
-
- @Bean
- public Redisson redisson() {
- Config config = new Config();
- //单个redis模式
- //config.useSingleServer().setAddress("redis://192.168.150.30:6379").setDatabase(10);//如果有设置密码 setPassword("123456")
-
- // redis集群模式
- List
redisCluster = Arrays.asList("redis://192.168.150.30:6379", "redis://192.168.150.31:6379", - "redis://192.168.150.32:6379");
- config.useClusterServers()
- .setPingConnectionInterval(20000)// 心跳检测 默认是30000
- .setScanInterval(2000) // 集群状态扫描时间间隔,默认值1000
- .setNodeAddresses(redisCluster);
- return (Redisson) Redisson.create(config);
- }
-
- }
- @Component
- public class RedisLock {
-
- @Autowired
- private Redisson redisson;
-
- public static final String lockKey = "redissonLockKey";
-
- public void redissonLock(int i) {
- RLock lock = redisson.getLock(lockKey);
- try {
- //开启看门狗 默认过期的时间是30秒
- lock.lock();
- // lock.lock(5000, TimeUnit.SECONDS); 不开启看门狗
- System.out.println("线程" + i + ":拿到锁了" + Thread.currentThread().getName());
- //这里写自己的业务 以下为测试数据
- try {
- System.out.println("线程" + i + "业务逻辑开始编写!");
- Thread.sleep(3000);
- System.out.println("线程" + i + "业务逻辑执行3秒");
- System.out.println();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- } finally {
- // 释放锁
- lock.unlock();
- }
- }
-
- }
注意点:看门狗机制
- //开启看门狗 默认过期的时间是30秒
- lock.lock();
- // lock.lock(5000, TimeUnit.SECONDS); 不开启看门狗
所谓的看门狗机制就是为了解决当前线程程序半路没有跑完,另一个线程获取到了锁的问题。比如你设置锁过期时间是3秒,但是你程序全部跑完需要5秒的时间,这个时候相当于你的程序中途跑到了一半,另一个线程获取到了锁也进入了,这个时候就没有办法保证数据原子性。redisson的看门狗机制就是,当你程序没有执行完的时候,这个锁过期时间会重新设置30s,保证当前程序执行完再释放。
源码分析:

也就是说,只有设置为-1的时候看门狗机制才会开启,如果你手动设置了锁过期时间,看门口机制是不会开启的。
- @RestController
- public class RedisLockController {
- @Autowired
- private RedisLock redisLock;
-
- @RequestMapping("/pool/test")
- public void poolTest() {
- //利用线程池方式测试分布式锁
- ExecutorService threadPool = Executors.newFixedThreadPool(10);
- for (int i = 0; i < 10; i++) {
- threadPool.submit(new RunTest(i, redisLock));
- }
- }
-
- @RequestMapping("/redis/test")
- public void test() {
- //利用单个线程的方式测试
- RunTest1 runnable1 = new RunTest1(redisLock);
- runnable1.run();
-
- RunTest2 runnable2 = new RunTest2(redisLock);
- runnable2.run();
-
- RunTest3 runnable3 = new RunTest3(redisLock);
- runnable3.run();
- }
-
- }
-
- class RunTest implements Runnable {
-
- private int i;
- private RedisLock redisLock;
-
- public RunTest(int i, RedisLock redisLock) {
- this.i = i;
- this.redisLock = redisLock;
- }
-
- @Override
- public void run() {
- redisLock.redissonLock(i);
- }
- }
-
- class RunTest1 implements Runnable {
-
- private RedisLock redisLock;
-
- public RunTest1(RedisLock redisLock) {
- this.redisLock = redisLock;
- }
-
- @Override
- public void run() {
- redisLock.redissonLock(1);
- }
- }
-
- class RunTest2 implements Runnable {
-
- private RedisLock redisLock;
-
- public RunTest2(RedisLock redisLock) {
- this.redisLock = redisLock;
- }
-
- @Override
- public void run() {
- redisLock.redissonLock(2);
- }
- }
-
- class RunTest3 implements Runnable {
-
- private RedisLock redisLock;
-
- public RunTest3(RedisLock redisLock) {
- this.redisLock = redisLock;
- }
-
- @Override
- public void run() {
- redisLock.redissonLock(3);
- }
- }

