28-高阶知识_StampedLock的使用
2.7 高阶知识:StampedLock的使用
StampedLock
类提供的锁和 Lock
或 ReadWriteLock
接口提供的有所不同, StampedLock
同样也不是两者的实现类,不过 StampedLock
类提供的功能和它们的功能却有些类似。
StampedLock
类最主要的存在意义就是为构建一个线程安全的组件提供工具类。因此该类在普通应用中可能并不常见。
以下是 StampedLock
类的几项主要特性。
- 开发者可以通过以下几种模式获得锁。
- 写 开发者在该模式下可以互斥地获得该锁。换句话说,在该模式下其他线程不能同时获得同一把锁。
- 读 开发者在该模式下可以以“非互斥”的方式获得锁。不过其他使用写锁模式和乐观读锁模式的线程不能同时获得同一把锁。
- 乐观读 开发者在该模式下并没有真正获得锁。其他线程仍然可以通过读锁模式获得同一把锁。当开发者希望获得通过乐观读锁保护共享变量时,需要额外检查当前是否可以访问该变量或者不使用
validate()
方法。
StampedLock
类中提供的方法将服务于以下情况。- 获得上述3种模式锁的控制权,如果使用类内的方法(
readLock()
、writeLock()
、readLockInterruptibly()
)无法获得锁,则当前线程将在获得锁之前保持挂起。 - 获得上述3种模式锁的控制权,如果通过类中的方法(
tryOptimisticRead()
、tryReadLock()
和tryWriteLock()
)无法获得锁,则方法将返回可以表示当前情况的特殊返回值。 - 锁模式的相互转换,无论成功还是失败,类中的这些方法(
asReadLock()
、asWriteLock()
和asReadWriteLock()
)都将返回对应的结果。 - 释放锁。
- 获得上述3种模式锁的控制权,如果使用类内的方法(
- 以上所有方法都会返回一个在锁中使用称为票据(stamp)的
long
型返回值。如果方法返回0,则表示当前线程获取锁失败。 StampedLock
接口并不是一个类似Lock
或者ReadWriteLock
的可重入锁。在线程中利用该方法再次获得一个锁后,将可能导致阻塞甚至死锁。- 该类型的锁并没有真正意义上的所有权概念,也就是说,一个锁内某个线程获取后可能随后又被其他线程所释放。
- 该锁对下一个即将获得锁的线程没有任何限制。
本节将介绍 StampedLock
接口在访问共享数据不同模式下的应用。本案例展示的是在3个并发任务中试验 StampedLock
锁3种不同的访问模式。