• springboot实现redisson分布式锁案例


    一、需要准备的maven包

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-redisartifactId>
    4. <version>1.4.7.RELEASEversion>
    5. dependency>
    6. <dependency>
    7. <groupId>org.redissongroupId>
    8. <artifactId>redissonartifactId>
    9. <version>3.17.4version>
    10. dependency>

    二、配置连接信息

    下面代码有单个redis配置和redis集群配置,需要修改成自己的redis地址

    1. @Configuration
    2. public class RedissonConfig {
    3. @Bean
    4. public Redisson redisson() {
    5. Config config = new Config();
    6. //单个redis模式
    7. //config.useSingleServer().setAddress("redis://192.168.150.30:6379").setDatabase(10);//如果有设置密码 setPassword("123456")
    8. // redis集群模式
    9. List redisCluster = Arrays.asList("redis://192.168.150.30:6379", "redis://192.168.150.31:6379",
    10. "redis://192.168.150.32:6379");
    11. config.useClusterServers()
    12. .setPingConnectionInterval(20000)// 心跳检测 默认是30000
    13. .setScanInterval(2000) // 集群状态扫描时间间隔,默认值1000
    14. .setNodeAddresses(redisCluster);
    15. return (Redisson) Redisson.create(config);
    16. }
    17. }

    三、测试业务逻辑编写

    1. @Component
    2. public class RedisLock {
    3. @Autowired
    4. private Redisson redisson;
    5. public static final String lockKey = "redissonLockKey";
    6. public void redissonLock(int i) {
    7. RLock lock = redisson.getLock(lockKey);
    8. try {
    9. //开启看门狗 默认过期的时间是30秒
    10. lock.lock();
    11. // lock.lock(5000, TimeUnit.SECONDS); 不开启看门狗
    12. System.out.println("线程" + i + ":拿到锁了" + Thread.currentThread().getName());
    13. //这里写自己的业务 以下为测试数据
    14. try {
    15. System.out.println("线程" + i + "业务逻辑开始编写!");
    16. Thread.sleep(3000);
    17. System.out.println("线程" + i + "业务逻辑执行3秒");
    18. System.out.println();
    19. } catch (InterruptedException e) {
    20. e.printStackTrace();
    21. }
    22. } finally {
    23. // 释放锁
    24. lock.unlock();
    25. }
    26. }
    27. }

    注意点看门狗机制

    1. //开启看门狗 默认过期的时间是30秒
    2. lock.lock();
    3. // lock.lock(5000, TimeUnit.SECONDS); 不开启看门狗

    所谓的看门狗机制就是为了解决当前线程程序半路没有跑完,另一个线程获取到了锁的问题。比如你设置锁过期时间是3秒,但是你程序全部跑完需要5秒的时间,这个时候相当于你的程序中途跑到了一半另一个线程获取到了锁也进入了,这个时候就没有办法保证数据原子性。redisson的看门狗机制就是,当你程序没有执行完的时候,这个锁过期时间会重新设置30s,保证当前程序执行完再释放

    源码分析:

     也就是说,只有设置为-1的时候看门狗机制才会开启,如果你手动设置了锁过期时间,看门口机制是不会开启的。

    四、测试接口

    1. @RestController
    2. public class RedisLockController {
    3. @Autowired
    4. private RedisLock redisLock;
    5. @RequestMapping("/pool/test")
    6. public void poolTest() {
    7. //利用线程池方式测试分布式锁
    8. ExecutorService threadPool = Executors.newFixedThreadPool(10);
    9. for (int i = 0; i < 10; i++) {
    10. threadPool.submit(new RunTest(i, redisLock));
    11. }
    12. }
    13. @RequestMapping("/redis/test")
    14. public void test() {
    15. //利用单个线程的方式测试
    16. RunTest1 runnable1 = new RunTest1(redisLock);
    17. runnable1.run();
    18. RunTest2 runnable2 = new RunTest2(redisLock);
    19. runnable2.run();
    20. RunTest3 runnable3 = new RunTest3(redisLock);
    21. runnable3.run();
    22. }
    23. }
    24. class RunTest implements Runnable {
    25. private int i;
    26. private RedisLock redisLock;
    27. public RunTest(int i, RedisLock redisLock) {
    28. this.i = i;
    29. this.redisLock = redisLock;
    30. }
    31. @Override
    32. public void run() {
    33. redisLock.redissonLock(i);
    34. }
    35. }
    36. class RunTest1 implements Runnable {
    37. private RedisLock redisLock;
    38. public RunTest1(RedisLock redisLock) {
    39. this.redisLock = redisLock;
    40. }
    41. @Override
    42. public void run() {
    43. redisLock.redissonLock(1);
    44. }
    45. }
    46. class RunTest2 implements Runnable {
    47. private RedisLock redisLock;
    48. public RunTest2(RedisLock redisLock) {
    49. this.redisLock = redisLock;
    50. }
    51. @Override
    52. public void run() {
    53. redisLock.redissonLock(2);
    54. }
    55. }
    56. class RunTest3 implements Runnable {
    57. private RedisLock redisLock;
    58. public RunTest3(RedisLock redisLock) {
    59. this.redisLock = redisLock;
    60. }
    61. @Override
    62. public void run() {
    63. redisLock.redissonLock(3);
    64. }
    65. }

    五、测试结果

    1)线程池测试结果

    2)单个线程测试结果

     

  • 相关阅读:
    linux中的vim工具
    关于HTTP协议的概述
    ubuntu软件安装和管理(apt-get)
    【计算机毕业设计】941高校宿舍管理系统
    SpringBoot 接口加密解密,新姿势!
    SpringBoot核心原理与实践
    SOC验证环境的启动方式
    Java集合框架
    git 常用命令
    数据、结构、数据结构之间的关系
  • 原文地址:https://blog.csdn.net/qq_36138652/article/details/126177603