Java并发 -- StampedLock
StampedLock VS ReadWriteLock
- StampedLock同样适用于读多写少的场景,性能比ReadWriteLock好
- ReadWriteLock支持两种模式:写锁、读锁
- StampedLock支持三种模式:写锁、悲观读锁、_乐观读_(关键)
- StampedLock的写锁、悲观读锁的语义和ReadWriteLock的写锁、读锁的语义非常类似
- 允许多个线程同时获取悲观读锁,只允许一个线程获取写锁,写锁和悲观读锁是互斥的
- 但StampedLock里的写锁和悲观读锁加锁成功之后,都会返回一个stamp,然后解锁的时候需要传入这个stmap
- StampedLock的写锁、悲观读锁的语义和ReadWriteLock的写锁、读锁的语义非常类似
1 | public class StampedLockExample { |
乐观读
- StampedLock的性能比ReadWriteLock要好的关键是StampedLock支持乐观读的方式
- ReadWriteLock支持多个线程同时读,但当多个线程同时读的时候,所有写操作都会被阻塞
- StampedLock提供的乐观读,是允许一个线程获取写锁的,并不是所有的写操作都会被阻塞
- 乐观读这个操作是无锁的,相对于ReadWriteLock的读锁,乐观读的性能要更好一点
1 | public class Point { |
数据库的乐观锁
1 | -- 假设version=9 |
注意事项
- StampedLock的功能仅仅是ReadWriteLock的_子集_
- StampedLock在命名上并没有增加Reentrant关键字,_不支持重入_
- StampedLock的悲观读锁、写锁都不支持条件变量
- 假设线程阻塞在StampedLock的readLock或者writeLock上
- 如果此时调用该阻塞线程的interrupt,会导致_CPU飙升_
- 使用StampedLock不要调用中断操作
- 如果需要支持中断功能,使用可中断的readLockInterruptibly或writeLockInterruptibly
1 | StampedLock lock = new StampedLock(); |
参考资料
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.