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 」获取最佳阅读体验并参与讨论