18. StampedLock: Is there a faster lock than a read-write lock? -Concurrency tools

StampedLock performance is better than read-write lock

1. Three lock modes supported by StampedLock

Three modes: write lock, pessimistic read lock and optimistic read . Among them, the semantics of write locks and pessimistic read locks are very similar to those of ReadWriteLock, which allows multiple threads to acquire pessimistic read locks at the same time, but only allows one thread to acquire write locks. Write locks and pessimistic read locks are mutual. Reprimanded. The difference is that the write lock and pessimistic read lock in StampedLock will return a stamp after the lock is successfully locked; then when unlocking, you need to pass in this stamp. The relevant sample code is as follows.

final StampedLock sl =  new StampedLock();
  
// 获取 / 释放悲观读锁示意代码
long stamp = sl.readLock();
try {
  // 省略业务相关代码
} finally {
  sl.unlockRead(stamp);
}
 
// 获取 / 释放写锁示意代码
long stamp = sl.writeLock();
try {
  // 省略业务相关代码
} finally {
  sl.unlockWrite(stamp);
}

ReadWriteLock supports multiple threads to read at the same time, but when multiple threads read at the same time, all write operations will be blocked; and the optimistic reads provided by StampedLock allow one thread to acquire the write lock, which means that not all write operations Are blocked. The optimistic read operation is lock-free .

class Point {
	private int x, y;
	final StampedLock sl = new StampedLock();

	// 计算到原点的距离
	int distanceFromOrigin() {
		// 乐观读
		long stamp = sl.tryOptimisticRead();
		// 读入局部变量,
		// 读的过程数据可能被修改
		int curX = x, curY = y;
		// 判断执行读操作期间,
		// 是否存在写操作,如果存在,
		// 则 sl.validate 返回 false
		if (!sl.validate(stamp)) {
			// 升级为悲观读锁
			stamp = sl.readLock();
			try {
				curX = x;
				curY = y;
			} finally {
				// 释放悲观读锁
				sl.unlockRead(stamp);
			}
		}
		return Math.sqrt(curX * curX + curY * curY);
	}
}

tryOptimisticRead () is optimistic reading. Reading x and y also needs to verify whether it has been changed. It is verified by validate (stamp). If it is changed, it is upgraded to a pessimistic read lock.

2. Further understand optimistic reading

Similar to the optimistic locking of the database. Optimistic locking of the database is achieved by increasing the version of the numeric field.

3. Precautions for using StampedLock

  • The function of StampedLock is only a subset of ReadWriteLock;
  • StampedLock does not support reentry;
  • StampedLock's pessimistic read locks and write locks do not support condition variables
  • If the thread is blocked on the readLock () or writeLock () of StampedLock, calling the interrupt () method of the blocked thread at this time will cause the CPU to soar. For example, in the following code, thread T1 blocks itself after acquiring a write lock, and thread T2 attempts to acquire a pessimistic read lock, and it also blocks; if you call thread T2's interrupt () method to interrupt thread T2, you will find thread T2 Your CPU will soar to 100%.
final StampedLock lock  = new StampedLock();
	Thread T1 = new Thread(()->{
	  // 获取写锁
	  lock.writeLock();
	  // 永远阻塞在此处,不释放写锁
	  LockSupport.park();
	});
	T1.start();
	// 保证 T1 获取写锁
	Thread.sleep(100);
	Thread T2 = new Thread(()->
	  // 阻塞在悲观读锁
	  lock.readLock()
	);
	T2.start();
	// 保证 T2 阻塞在读锁
	Thread.sleep(100);
	// 中断线程 T2
	// 会导致线程 T2 所在 CPU 飙升
	T2.interrupt();
	T2.join();

When using StampedLock, you must not call the interrupt operation. If you need to support the interrupt function, you must use the interruptible pessimistic read lock readLockInterruptibly () and write lock writeLockInterruptibly ().

StampedLock read template:

final StampedLock sl = 
  new StampedLock();
 
// 乐观读
long stamp = 
  sl.tryOptimisticRead();
// 读入方法局部变量
......
// 校验 stamp
if (!sl.validate(stamp)){
  // 升级为悲观读锁
  stamp = sl.readLock();
  try {
    // 读入方法局部变量
    .....
  } finally {
    // 释放悲观读锁
    sl.unlockRead(stamp);
  }
}
// 使用方法局部变量执行业务操作
......

StampedLock write template:

long stamp = sl.writeLock();
try {
  // 写共享变量
  ......
} finally {
  sl.unlockWrite(stamp);
}
Published 97 original articles · praised 3 · 10,000+ views

Guess you like

Origin blog.csdn.net/qq_39530821/article/details/102646900