ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

项目中分布式锁的实现方式(技术篇)

2022-02-04 13:29:59  阅读:222  来源: 互联网

标签:redisson return String 方式 项目 lock park 加锁 分布式


前提:使用redis实现分布式锁

1.在pom文件中导入java对redis分布式锁的支持依赖:

<!--        实现分布式锁依赖-->
        <!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.16.8</version>
        </dependency>

2.编写配置类

@Configuration
public class MyRedissonConfig {
    /**
     * destroyMethod定义销毁方法
     * @return
     */
    @Bean(destroyMethod = "shutdown",value = "redisson")
    RedissonClient getRedissonClient(){
        //创建配置
        Config config = new Config();
        //这里的redis地址是你自己的
        config.useSingleServer().setAddress("redis://158.72.233.198:6379");
        //根据config创建出实例
        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;

    }
}

3.分布式锁的原理

        redis分布式锁与JUC的Lock锁的实现基本一致,lock()方法加锁,unlock()方法解锁
        1.可重入锁(Reentrant Lock):如果在锁的内部有嵌套锁,并且是同一把锁的话,内部可以直接执行,即内部可以使用外部锁  

@GetMapping("hello")
    @ResponseBody
    public String hello() {
        //使用分布式锁,通过锁客户端->取得一把锁,并定义锁名字,只要锁的名字一致就是同一把锁
        //RLock继承与lock
        RLock lock = redisson.getLock("my-lock");
        //加锁
        //如果我们传递了锁的超时时间,就发送redis脚本,进行占锁,默认超时时间就是我们指定的时间
        //如果我们没有传递锁超时时间,就使用看门狗的30*1000,后端会通过异步编排的定时器机制,发现线程还在运行,并且在10s,调用方法重新延时为30s
        lock.lock();//这个加锁是阻塞式等待
        //锁的自动续期,如果业务超长,每当运行到默认时间的/3,自动给锁续上30秒(看门狗机制)
        try {
//            取得线程id
            System.out.println("加锁成功,执行业务...."+Thread.currentThread().getId());
            Thread.sleep(30000);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //解锁,此处即使代码没有运行也会解锁,因为看门狗机制
            lock.unlock();
            System.out.println("解锁成功...."+Thread.currentThread().getId());
        }
        return "hello";
    }

        2.公平锁(Fair Lock):它保证当多个redisson客户端线程同时请求加锁时,优先分配给先发出请求的线程

   @GetMapping("read")//读锁是共享锁
    @ResponseBody
    public String readValue(){
        //获取读写锁对象
        RReadWriteLock lock = redisson.getReadWriteLock("rw-lock");
        //获取读锁
        RLock rLock = lock.readLock();
        String s = "";
        try {
            rLock.lock();//加锁
            s = stringRedisTemplate.opsForValue().get("writeValue");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            rLock.unlock();//解锁
        }
        return s;
    }

    @GetMapping("write")//写锁是排他锁
    @ResponseBody
    public String writeValue(){
        //获取读写锁对象
        RReadWriteLock lock = redisson.getReadWriteLock("rw-lock");
        //改数据用写锁
        RLock rLock = lock.writeLock();
        String s = "";
        try {
            rLock.lock();//加锁
            s = UUID.randomUUID().toString().replaceAll("-","");
            Thread.sleep(30000);
            //将s放入到缓存中
            stringRedisTemplate.opsForValue().set("writeValue",s);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            rLock.unlock();//解锁
        }
        return s;
    }

4.信号量(Semaphore):基于redis的redisson的分布式信号量,类似于占车位

/**
     * 车库停车
     * 3车位
     */
    @GetMapping("park")//停车方法
    @ResponseBody
    public String park() throws InterruptedException {
        //取得信号量对象
        RSemaphore park = redisson.getSemaphore("park");
        //park.acquire();//获取一个信号,获取一个值,占一个车位,阻塞式获取
        boolean b = park.tryAcquire();//尝试获取如果没有直接进行返回
        return "ok";
    }

    @GetMapping("go")//开车走方法
    @ResponseBody
    public String go(){
        //取得信号量对象
        RSemaphore park = redisson.getSemaphore("park");
        park.release();//释放车位
        return "ok";
    }

5.闭锁(CountDownLatch):基于redis的redisson的分布式闭锁,类似于放假锁门

/**
     * 放假,锁门
     * 需要五个班都走完,才能锁门
     */
    @GetMapping("lockDoor")
    @ResponseBody
    public String lockDoor() throws InterruptedException {
        //获取闭锁对象
        RCountDownLatch door = redisson.getCountDownLatch("door");
        //设置需要关闭的数量
        door.trySetCount(5);
        door.await();//等待闭锁都完成
        return "放假了";
    }
    @GetMapping("gogogo/{id}")
    @ResponseBody
    public String gogogo(@PathVariable("id")String id){
        //获取闭锁对象
        RCountDownLatch door = redisson.getCountDownLatch("door");
        door.countDown();//计数减一
        return id+"班人走完了...";
    }

标签:redisson,return,String,方式,项目,lock,park,加锁,分布式
来源: https://blog.csdn.net/qq_1757537040/article/details/122782123

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有