乐观锁与悲观锁
乐观锁:既假设锁冲突的概率比较低基本没有冲突,简单的处理冲突。
悲观锁:既假设锁冲突的概率比较高基本每次尝试加锁都会产生锁冲突,付出更多的成本处理冲突。
Synchronized初始使用乐观锁策略。当发现锁竞争比较频繁的时候就会自动切换成悲观锁策略。
乐观锁的一个重要功能就是检测数据是否发生冲突。引入“版本号”解决。
如修改账户余额:提交版本号必须大于记录当前版本号才能执行更新
读写锁
线程对于数据的访问,主要存在两种操作:读操作和写操作。
- 两个读线程之间,其实不存在线程安全,就不必互斥。
- 两个写线程之间,存在线程安全,需要互斥。
- 一个读线程一个写线程,存在线程安全,就需要互斥。
在有些场景中,本来就写比较少,读比较多。
Synchronized并没有对读写进行区分,只要使用就一定互斥,像这种读比较多写比较少的情景效率就比较低。此时就需要读写锁。
Java标准库里就提供了这个类:
- ReentrantReadWriteLock.ReadLock能够构造一个读锁实例,提供了lock/unlock方法进行加锁解锁.
- ReentrantReadWriteLock.WriteLock能够构造一个写锁实例,提供 lock/un