常用到的多种锁(随时可能修改)

在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分布式锁

 

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

这个性能上待测试

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

时间: 2024-12-05 23:32:28

常用到的多种锁(随时可能修改)的相关文章

​随时笔记---修改ip访问外网

随时笔记---修改ip访问外网 Linux环境: 网卡上增加一个IP: ifconfig eth0:1 192.168.0.1 netmask 255.255.255.0 删除网卡的第二个IP地址: ip addr del 192.168.0.1 dev eth0 这种方式增加的虚拟IP,可以通过ifconfig查看 另一种增加虚拟IP的方法(ifconfig查看不到): 增加虚拟IP: ip -f inet addr add 192.168.146.229/32 brd 192.168.146

Android 常用工具类之SPUtil,可以修改默认sp文件的路径

参考: 1. 利用Java反射机制改变SharedPreferences存储路径    Singleton1900 2. Android快速开发系列 10个常用工具类 Hongyang import android.app.Activity; import android.content.Context; import android.content.ContextWrapper; import android.content.SharedPreferences; import java.io.

报表性能优化方案之多种报表服务器内存修改方法

服务器内存修改 各应用服务器的内存配置方法不尽相同,如下列出了常用服务器的JVM参数(-Xms,-Xmx)配置方法. JVM参数定义: - Xms: 初始化内存大小 - Xmx: 可以使用的最大内存 示例工具 以下示例工具:报表开发工具FineReport Tomcat服务器内存修改 1. 问题描述 java应用程序运行过程中会使用web应用服务器的内存,如执行报表获取的数据,运算的中间数据等都需要暂存在服务器内存中. 当没有空内存可用时,就会出现内存溢出错误:java.lang.OutOfMe

Linux中常用的操作指令(随时更新)

CentOS 防火墙放开端口 #sudo /sbin/iptables -I INPUT -p tcp --dport 3690 -j ACCEPT //开启防火墙端口: #/etc/init.d/iptables save //保存修改 service iptables restart // 重启防火墙,修改生效

简单的常用标签以及属性(随时补充)

HTML类别 table  表格  属性:1.cellpadding  单元格内部与边框的距离   2.cellspacing  每个单元格之间的间距 td 表中的单元格     属性 colspan="值"   将单元格横向合并指定值 input 输入框  属性:1.type="text"  常用输入框 ,可获取数字,符号,文字,字母等 2.type="password"  密码输入框,显示内容为点或者星号,实际内容不变 3.type=&quo

解决并发问题,数据库常用的两把锁——悲观锁,乐观锁

一.概念: 乐观锁:适用于写少读多的情景,因为这种乐观锁相当于java的cas(比较并替换),所以多条数据同事过来的时候不用等待,可以立即进行返回 悲观锁:适用于写多读少的情景,这种情况也相当于java的synchronized,reentrantLock等,大量数据过来的时候,只有一条被写入,其他数据需要等待,智行完成后下一条数据继续. 二:实现方式: 乐观锁:采用版本号的方式.即当前版本号如果对应上了就可以写入数据,如果判断当前版本号不一致,那么就不会更新成功. 比如 update tabl

Python3常用学习网站总结(随时更新)

Python资源大全 http://python.jobbole.com/84464/ https://github.com/jobbole/awesome-python-cn scrapy: https://scrapy-chs.readthedocs.io/zh_CN/1.0/intro/tutorial.html http://scrapy-chs.readthedocs.io/zh_CN/latest/intro/tutorial.html https://scrapy.org/ htt

dockerfile编辑时常用的sed命令,用来修改配置文件。

sed 替换部分文件内容 随着使用,会逐步更新. #替换整行sed '/mengqingbo/c lanqiuxiaozi="FALSE"' fileName #匹配行前加sed -i '/allow 361way.com/iallow www.361way.com' fileName#匹配行后加sed -i '/allow 361way.com/aallow www.361way.com' fileName #删除最后一行sed -i '$d' fileName #最后一行插入sed

oralce数据库常用到的一些sql命令(加字段注释,修改数据之类)

最近开始接触oralce,整理了一下最近使用 pl/sql 常用到的一些sql命令 1.修改表中的数据 编写查询语句及条件,然后加上"FOR UPDATE","FOR UPDATE"是获得OACLE的修改权限,执行这条查询语句,查询出对应的记录 select * from sys_svr FOR UPDATE 2.向一个表中添加字段和注释 alter table appr_control_info_ex add control_seq VARCHAR2(30); -