StampedLock类的简介
StampedLock类,在JDK1.8时引入,是对读写锁ReentrantReadWriteLock的增强,该类提供了一些功能,优化了读锁、写锁的访问,同时使读写锁之间可以互相转换,更细粒度控制并发。它的特点是在使用读锁、写锁时都必须配合【戳】使用,如:
这个戳通常会配合该类的tryOptimisticRead方法使用,tryOptimisticRead方式采用的是乐观读的思想。在ReentrantReadWriteLock中,当读锁被使用时,如果有线程尝试获取写锁,该写线程会阻塞。但是,在Optimistic reading中,即使读线程获取到了读锁,写线程尝试获取写锁也不会阻塞,这相当于对读模式的优化,但是可能会导致数据不一致的问题。所以,当使用Optimistic reading获取到读锁时,必须对获取结果使用戳进行校验。
StampedLock的特点
- StampedLock 是从 JDK1.8 开始提供,它的性能比 ReadWriteLock 好
- StampedLock 支持:乐观读锁、悲观读锁、写锁
- StampedLock 不支持重入
- StampedLock 支持锁的降级和升级 (即乐观读锁升级为写锁)
StampedLock 无论写锁还是读锁,都不支持Conditon等待
StampedLock使用示例
@Slf4j(topic = "c.DataContainerStamped")public class DataContainerStamped {private int data;private final StampedLock lock = new StampedLock();public DataContainerStamped(int data) {this.data = data;}public void read(int readTime) throws InterruptedException {long stamp = lock.tryOptimisticRead();log.debug("optimistic read locking...{}", stamp);Thread.sleep(readTime * 1000L);//validate方法用于验戳,即验证数据是否被修改if (lock.validate(stamp)) {log.debug("read finish...{}, data:{}", stamp, data);return;}// 锁升级 - 读锁(悲观读锁)log.debug("updating to read lock... {}", stamp);try {stamp = lock.readLock();log.debug("read lock {}", stamp);Thread.sleep(readTime * 1000L);log.debug("read finish...{}, data:{}", stamp, data);} finally {log.debug("read unlock {}", stamp);lock.unlockRead(stamp);}}public void write(int newData) throws InterruptedException {long stamp = lock.writeLock();log.debug("write lock {}", stamp);try {Thread.sleep(2 * 1000L);this.data = newData;} finally {log.debug("write unlock {}", stamp);lock.unlockWrite(stamp);}}}
测试代码:
public static void main(String[] args) throws InterruptedException {DataContainerStamped dataContainer = new DataContainerStamped(1);new Thread(() -> {try {dataContainer.read(1);} catch (InterruptedException e) {e.printStackTrace();}}, "t1").start();new Thread(() -> {try {dataContainer.write(2);} catch (InterruptedException e) {e.printStackTrace();}}, "t2").start();}
测试结果:

可以看到在“01:28:24”,t1获取乐观读锁,随后t2获取写锁,t2并没有被阻塞,因此验证了可以从乐观读锁升级为写锁的特点。StampedLock 相比于读写锁有很多优点,但是有两个比较大的缺点:- StampedLock 不支持条件变量
- StampedLock 不支持可重入
