乐观锁
乐观思想:认为读多写少,遇到并发写的可能性很低。取数据的时候总认为不会有其他线程对数据进行修改,所以不会上锁
但是在更新的时候会判断一下在此期间别人有没有去更新这个数据(一般会使用版本号机制或CAS操作实现。),采取在写时先读出当前版本号,然后加锁操作(比较跟上一次的版本号,如果一样则更新),如果失败则要重复读-比较-写的操作。
java 中的乐观锁基本都是通过 CAS 操作实现的, CAS 是一种更新的原子操作, 比较当前值跟传入值是否一样,一样则更新,否则失败。
1、version方式:
一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加一。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。
2、CAS操作:
即compare and swap 或者 compare and set,涉及到三个操作数,数据所在的内存值,预期值,新值。当需要更新时,判断当前内存值与之前取到的值是否相等,若相等,则用新值更新,若失败则重试,一般情况下是一个自旋操作,即不断的重试。
悲观锁
悲观思想:认为写多,遇到并发写的可能性很高。取数据的时候总认为有其他线程对数据进行修改,所以每次在读写数据的时候都会上锁,这样别人想读写这个数据就会 block (阻塞挂起)直到拿到锁。在Java中,synchronized的思想也是悲观锁。
借鉴:https://blog.csdn.net/L_BestCoder/article/details/79298417