public class StampedLockExample { private final StampedLock stampedLock = new StampedLock(); @Test // 悲观读锁 public void pessimisticReadLockTest() { long stamp = stampedLock.readLock(); try { // 业务逻辑 } finally { stampedLock.unlockRead(stamp); } } @Test // 写锁 public void writeLockTest() { long stamp = stampedLock.writeLock(); try { // 业务逻辑 } finally { stampedLock.unlockWrite(stamp); } } }
public class Point { private int x, y; private final StampedLock stampedLock = new StampedLock(); // 计算到原点的距离 public double distanceFromOrigin() { // 乐观锁(无锁算法,共享变量x和y读入方法局部变量时,x和y有可能被其他线程修改) long stamp = stampedLock.tryOptimisticRead(); // 读入局部变量,读的过程中,数据可能被修改 int curX = x; int curY = y; // 判断执行读操作期间,是否存在写操作,如果存在,validate会返回false if (!stampedLock.validate(stamp)) { // 升级为悲观读锁 // 如果不升级,有可能反复执行乐观读,浪费大量CPU stamp = stampedLock.readLock(); try { curX = x; curY = y; } finally { // 释放悲观读锁 stampedLock.unlockRead(stamp); } } return Math.sqrt(curX * curX + curY * curY); } }
-- 假设version=9 SELECT id,...,version FROM product_doc WHERE id=777; -- version类似于StampedLock的stamp UPDATE product_doc SET version=version+1,... WHERE id=777 AND version=9;
StampedLock lock = new StampedLock(); Thread t1 = new Thread(() -> { // 获取写锁 lock.writeLock(); // 永远阻塞,不释放写锁 LockSupport.park(); }); t1.start(); // 保证t1获得写锁 TimeUnit.SECONDS.sleep(1); Thread t2 = new Thread(() -> { // 阻塞在悲观读锁 lock.readLock(); }); t2.start(); // 保证t2阻塞在悲观读锁 TimeUnit.SECONDS.sleep(1); // 导致t2所在的CPU飙升 t2.interrupt(); t2.join();
转载请注明出处:http://zhongmingmao.me/2019/05/10/java-concurrent-stamped-lock/
访问原文「 Java并发 -- StampedLock 」获取最佳阅读体验并参与讨论