Java实现分布式锁 总结

高并发问题是我们前进路上必须要解决的问题,现对使用实现分布式锁进行下总结

为什么使用分布式锁

在遇到多线程问题的时候,我们一般第一反应就是进行加锁,而synchronized是我们最熟悉的方式,确实可以解决并发问题,但是synchronized是基于jvm的,所以在分布式环境下,并不能满足多个系统访问只有一个线程可以访问资源的需求,所以这时候就需要使用分布式锁。
分布式锁实现一般是三种方式

  • 通过数据库实现
  • 通过redis实现
  • 通过zookeeper实现

三种方式说白了也就是多个系统访问同一个资源,由这一个资源进行单一线程执行控制。

数据库实现分布式锁

数据库实现分布式锁一般是使用数据表中的唯一约束,比如创建一个有唯一约束的字段,多个系统同时进行访问的时候,都向系统中插入一条记录,插入成功则代表获得了锁,没有成功则说明已有线程抢先一步,等有锁的线程执行成功后在删除记录。
这只是一种方式,通过数据库还有多种别的方式进行控制。缺点就是要和和数据库进行交互,耗费与数据库连接的资源。而且出了意外后不容易解决,有可能获取锁后挂掉,数据库中数据一直存在,锁得不到释放。

redis实现分布式锁

这之中使用最广泛的应该就是redis了吧,redis是直接访问内存资源,速度也比较快。
redis实现分布式锁主要在于setnx()方法,这个方法实现是在设置值得时候,先看当前的key是否存在,若key已经存在,则不会进行插入。通过返回的值0失败1成功可以判断自己是否获得了锁。
具体实现只要会在java中使用redis基本都会写了,就不写示例了。

zookeeper实现分布式锁

zookeeper实现,主要是运用了zookeeper中的临时顺序,在创建节点时,Zookeeper根据创建的时间顺序给该节点名称进行编号;当创建节点的客户端与zookeeper断开连接后,临时节点会被删除。
当多个线程想要获取锁得时候,先向一个持久节点下建立一个临时节点,然后查找这个持久节点下的所有节点,看自己的节点是否排在第一个,如果是第一个,则获得锁,如果不是,则建立watcher监视自己前面的一个节点,进行等待,当前面的节点被删除后,则自己获得锁。
这种方式实现的优点是可以通过顺序获得锁,不会像redis一样没有获得锁则进行自旋重新抢锁。可以解决饥饿锁问题。缺点就是消耗资源相对较多。

目前来说使用redis实现是比较好的方式,当然,如果项目中没有用的redis的话也不用专门加一个redis来做锁,不过一般分布式项目都会用到redis吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值