java程序实现分布式锁

三种实现方式:
1. 数据库乐观锁(使用SQL语句);
2. 基于Redis的分布式锁;
3. 基于ZooKeeper的分布式锁(并发量很高)。

基于Redis的分布式锁流程详解:
悲观锁
C1获取锁,并崩溃。C2和C3调用SETNX上锁返回0后,调用GET命令获得foo.lock的时间戳T1,通过比对时间戳,发现锁超时。
C4 向foo.lock发送GESET命令,
GETSET foo.lock <current unix time>
并得到foo.lock中老的时间戳T2

如果T1=T2,说明C4获得时间戳。
如果T1!=T2,说明C4之前有另外一个客户端C5通过调用GETSET方式获取了时间戳,C4未获得锁。只能sleep下,进入下次循环中(由于进程/线程之间时间戳差距很小,不影响正常的逻辑)。
注:设置key时,也可以设置超时时间来解决超时bug。

乐观锁-使用事务(级别是读提交)
事务的命令:
1.multi,开启Redis的事务,置客户端为事务态。 
2.exec,提交事务,执行从multi到此命令前的命令队列,置客户端为非事务态。 
3.discard,取消事务,置客户端为非事务态。 
4.watch,监视键值对,作用时如果事务提交exec时发现监视的监视对发生变化,事务将被取消。
5.unwatch,取消监听。
说明:redis的事务级别是读提交,其它的操作也会对事务结果有影响。所以事务只是用来保证原子性。

要实现乐观锁,只能使用watch机制,watch使用说明如下:
1. 乐观锁的实现,必须基于WATCH,然后利用redis的事务。
2. WATCH生命周期,只是和事务关联的,一个事务执行完毕,相应的watch的生命周期即结束。

发布了31 篇原创文章 · 获赞 1 · 访问量 1166

猜你喜欢

转载自blog.csdn.net/quietbxj/article/details/104037625