博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
常用到的多种锁(随时可能修改)
阅读量:5206 次
发布时间:2019-06-14

本文共 1025 字,大约阅读时间需要 3 分钟。

在Java内存模型中,有main memory,每个线程也有自己的memory (例如寄存器)。为了性能,一个线程会在自己的memory中保持要访问的变量的副本。这样就会出现同一个变量在某个瞬间,在一个线程的memory中的值可能与另外一个线程memory中的值,或者main memory中的值不一致的情况。 

 
violate 并不是锁,只是规定该变量不允许使用备份(缓存),只能从内存读写,但这并不说是线程安全的。
 

原因:Volatile一般情况下不能代替sychronized,因为volatile不能保证操作的原子性,即使只是i++,实际上也是由多个原子操作组成:read i; inc; write i,假如多个线程同时执行i++,volatile只能保证他们操作的i是同一块内存,但依然可能出现写入脏数据的情况。如果配合Java 5增加的atomic wrapper classes,对它们的increase之类的操作就不需要sychronized。 

 

广义重入锁  递归调用的时候,同一线程能不能再次获得锁 

 
ReentrantLock 
 
    - 没有线程持有锁的时候,state为0。
    - 当某个线程获取锁时,state的值增加,具体增加多少开发人员可自定义,默认为1,表示该锁正在被一个线程占有。
    - 当某个已经占用锁的线程再次获取到锁时,state再增长,此为重入锁。
    - 当占有锁的线程释放锁时,state也要减去当初占有时传入的值,默认为1。
 
 
 
数据库悲观锁
 
update 或者手动获取锁(for update)
 
索引列是锁索引筛选到的列(无需全表扫描)
 
其他列锁表(全表扫描)
 
(多个查询条件也不影响上面的逻辑,所以库存扣减完全可以限制id+库存>0 来update获取行数)
 
乐观锁
 

需要自己实现,常用做法是记录一个递增的version,提交时候验证

 
Redis实现分布式锁
 

利用setIf来实现,网上提供的例子中,锁不能保证公平性,而且自定义的sleep容易导致线程堵死,加超时时间又和业务违背(请求失败)

目前没有发现好的策略
 
Zookeeper分布式锁
 

利用临时自增节点的特性,观察某个节点,然后每次有变化查看自己是不是最小的,如果是最小的,那么执行,不是最小的,继续等待。

这个性能上待测试

 

 

看到有错,麻烦指出谢谢!

转载于:https://www.cnblogs.com/luochengqiuse/p/4921247.html

你可能感兴趣的文章
对位与字节的深度认识
查看>>
C++编程基础二 16-习题4
查看>>
MongoDB遇到的疑似数据丢失的问题。不要用InsertMany!
查看>>
服务器被疑似挖矿程序植入107.174.47.156,发现以及解决过程(建议所有使用sonatype/nexus3镜像的用户清查一下)...
查看>>
类型“XXX”的控件“XXXX”必须放在具有 runat=server 的窗体标记内。
查看>>
JQuery 学习
查看>>
session token两种登陆方式
查看>>
C# ArrayList
查看>>
IntelliJ IDEA 12集成Tomcat 运行Web项目
查看>>
java,多线程实现
查看>>
个人作业4-alpha阶段个人总结
查看>>
android smack MultiUserChat.getHostedRooms( NullPointerException)
查看>>
递归-下楼梯
查看>>
实用的VMware虚拟机使用技巧十一例
查看>>
监控工具之---Prometheus 安装详解(三)
查看>>
Azure Iaas基础之---创建虚拟机
查看>>
不错的MVC文章
查看>>
网络管理相关函数
查看>>
IOS Google语音识别更新啦!!!
查看>>
20190422 T-SQL 触发器
查看>>