redission 实现分布式锁

5 篇文章 1 订阅
3 篇文章 0 订阅

1.原理

图片
2.高效分布式锁

当我们在设计分布式锁的时候,我们应该考虑分布式锁至少要满足的一些条件,同时考虑如何高效的设计分布式锁,这里我认为以下几点是必须要考虑的。

1、互斥

在分布式高并发的条件下,我们最需要保证,同一时刻只能有一个线程获得锁,这是最基本的一点。

2、防止死锁

在分布式高并发的条件下,比如有个线程获得锁的同时,还没有来得及去释放锁,就因为系统故障或者其它原因使它无法执行释放锁的命令,导致其它线程都无法获得锁,造成死锁。

所以分布式非常有必要设置锁的有效时间,确保系统出现故障后,在一定时间内能够主动去释放锁,避免造成死锁的情况。

3、性能

对于访问量大的共享资源,需要考虑减少锁等待的时间,避免导致大量线程阻塞。

所以在锁的设计时,需要考虑两点。

1、锁的颗粒度要尽量小。比如你要通过锁来减库存,那这个锁的名称你可以设置成是商品的ID,而不是任取名称。这样这个锁只对当前商品有效,锁的颗粒度小。

2、锁的范围尽量要小。比如只要锁2行代码就可以解决问题的,那就不要去锁10行代码了。

4、重入

我们知道ReentrantLock是可重入锁,那它的特点就是:同一个线程可以重复拿到同一个资源的锁。重入锁非常有利于资源的高效利用。关于这点之后会做演示。

针对以上Redisson都能很好的满足,下面就

3.代码案例
a.依赖

引入依赖

maven

  •  
  •  
  •  
  •  
  •  
<dependency>    <groupId>org.redisson</groupId>    <artifactId>redisson</artifactId>    <version>3.14.0</version></dependency>
 

 

gradle
 

  •  
  compile('org.redisson:redisson:3.14.0')
 
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
    //单机    @Bean    public Redisson redisson() {        Config config = new Config();        config.useSingleServer()                .setAddress("redis://127.0.0.1:6379")                .setDatabase(1);        RedissonClient redisson = Redisson.create(config);        return (Redisson) redisson;    }        主从////    Config config = new Config();//    config.useMasterSlaveServers()//        .setMasterAddress("127.0.0.1:6379")//    .addSlaveAddress("127.0.0.1:6389", "127.0.0.1:6332", "127.0.0.1:6419")//    .addSlaveAddress("127.0.0.1:6399");//    RedissonClient redisson = Redisson.create(config);//////    //哨兵//    Config config = new Config();//    config.useSentinelServers()//        .setMasterName("mymaster")//    .addSentinelAddress("127.0.0.1:26389", "127.0.0.1:26379")//    .addSentinelAddress("127.0.0.1:26319");//    RedissonClient redisson = Redisson.create(config);//////    //集群//    Config config = new Config();//    config.useClusterServers()//        .setScanInterval(2000) // cluster state scan interval in milliseconds//    .addNodeAddress("127.0.0.1:7000", "127.0.0.1:7001")//    .addNodeAddress("127.0.0.1:7002");//    RedissonClient redisson = Redisson.create(config);

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
package com.example.demo;
import lombok.extern.slf4j.Slf4j;import org.redisson.Redisson;import org.redisson.api.RLock;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;import java.util.concurrent.TimeUnit;
/** * @author : chenye * @date : 2020-12-17 */@Slf4j@RestControllerpublic class MyController {    @Resource    private Redisson redisson;
    /**     * localhost:8080?a=test1     * localhost:8080?a=test2     */    @GetMapping("/")    public String test(String a) {        RLock lock = redisson.getLock("myProduct");        lock.lock(30, TimeUnit.SECONDS);        try {            for (int i = 0; i < 900000; i++) {                log.info(a + "," + i);            }            //doSomething        } finally {            lock.unlock();        }        return "操作完成";    }
}

 

推荐文章

ConcurrentHashMap原理分析

多线程学习(一) 线程与进程的理解

多线程学习(二) 多线程创建4种方式

Redis数据迁移的4种方法
JVM工作原理

mysql 实现查询排行榜

 

图片

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java知路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值