【听课笔记】java分布式锁

课程链接

课程:https://url.163.com/VD8

java锁

synchronized

在jdk 1.5以后,优化了,使其性能并不是像很多帖子说的那样,“非常重”

JUC lock

方法说明
lock()获取锁,如果锁被暂用则一直等待
tryLock()如果获取锁的时候锁被占用就返回false,否则返回true
tryLock(long time, TimeUnit unit)比起tryLock,多出等待时间
unLock()
lockInterruptibly()

lock与synchronized区别

  • lock是接口,syn是java关键字,是内置实现;
  • sync 发生异常时自动释放线程占有的锁,因此不会导致死锁现象发生;lock在发生异常时,如果没有unLock去释放锁,可能造成死锁。因此使用lock时需要在finally中释放锁
  • lock 可以让等待锁的线程响应中断;sync 不行,使用sync等待线程一直等待下去,不能中断
    lock可以知道有没有成功获得锁,sync则无法知道
  • lock可提高多线程读效率

性能上,竞争不激烈,两者性能;竞争激烈时,lock性能远由于sync。具体需要根据情况而定。
并不一定总是需要用lock,sync更方便,lock需要更精心维护代码、避免死锁

分布式锁

push
pull
的方式

惊群效应

分布式锁需要具备的条件:

  • 互斥性
  • 可重入
  • 超时高效
  • 阻塞/非阻塞

几种实现方式:

  1. 数据库实现(乐观锁)
  2. 基于zookeeper的实现
  3. 基于redis的实现
  4. 自研分布式锁(google的chubby, zookeeper实际上是基于这个chubby)

基于数据库实现

基于redis的实现

基本命令

SETNX key value   

if key不存在,则设置为value;存在则不做任何操作
“SET if Not eXist”

expire key seconds 

设置过期时间,如果key已国企,则将会被自动删除。

del key

删除key

实现方式

基本锁

原理:利用redis的setnx,如果不存在某个key则设置值,设置成功则表示锁成功
缺点:如果获取锁后的进程在没有执行完就挂了,则锁永远不会释放

改进型

改进:在基本形式锁上setnx后设置expire,保证超时后也能自动释放锁
缺点:setnx与expire不是一个原子操作,可能执行完setnx该进程就挂了

再改进

lua执行具有原子性
改进:利用lua脚本,将setnx与expire编程一个原子操作,可解决一部分问题
缺点:还是会出现锁过期的问题

具体实现

官方提供的java组件:redisson
redisson的分布式可重入锁RLock java对象实现了java.util.concurrent.locks.lock接口同时还支持过期解锁
地址:

分布式锁方案比较

  • 从理解的难易程度(从低到高)
    数据库 > 缓存 > zookeeper
  • 从实现的复杂性角度
    zookeeper >= 缓存 > 数据
  • 从性能角度(从高到底)
    缓存 > zookeeper >= 数据库
  • 从可靠性角度(从高到低)
    zookeeper > 缓存 > 数据库

扩展

redis的可以用于哪些场景?

  • 缓存
  • 消息队列
  • 分布式锁
  • 发布订阅
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值