悲观锁
思想
认为事务处理的情况总是悲观的,所以每次事务操作都会上锁(只允许自己操作,其他线程不能)。
实现
1)数据库(例如:MySQL)自带的读锁、写锁、行锁等 2)Java的synchronized关键字
乐观锁
思想
认为事务处理的情况总是乐观的,所以每次事务操作都不会上锁(顶多做一些数据校验)。
实现
1)数据表中增加version字段(int型),每次操作数据时都比较version的值,如果和预期值一样则允许下一步操作,接着version增加1,否则退出。
2)CAS(Compare And Swap)比较与交换。涉及3个值,存储值,预期值,新存储值。当新存储值出现时,将存储值与预期 值相比较,如果相等(就是我认为这个值在我操作的过程中其他线程没有操作过),则将存储值更新为新存储值,否则退出。
但是CAS可能会出现ABA现象:如果线程1在操作V值(存储值为A)的过程中,认为只要V值等于A就相当于是安全的,但是实际上线程2也在操作V值,并且把V值修改为B然后又修改回了A,此时线程1还是认为V值没有被其他线程操作过。因为CAS只是单纯地比较值,因此值发了变化表面上看跟没发生了一样,不像版本号version,会有自增的记录。不过ABA现象可能对于大多数业务来说不是什么问题,可能大家只关心结果不关心过程,所以具体场景具体分析。
实例为Java并发包原子操作类中的方法,但是会有自旋(不成功就一直循环执行直到成功)导致内存开销大。