此comparison of StampedLock and other locks表明StampedLock是竞争加剧时最快的。然而,这篇以及其他各种文章都没有列出为什么它更快。它似乎使用与其他类型的锁相同的CAS语义?任何人都可以解释为什么争用上升最快?
例如,在此代码的下面,writeLock不仅会阻塞其他writeLocks,还会阻塞readLocks。此时我并不关心optimisticReadLocks等。只是简单的writeLock ..什么是优势,它如何比ReentrantLock更快(加上它甚至没有重入)。
public static void main(String[]args)throws Exception{
StampedLock lk = new StampedLock();
new Thread(() -> {
long stamp = lk.writeLock();
try {
out.println("locked.. sleeping");
TimeUnit.SECONDS.sleep(5);
lk.unlock(stamp);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
long stamp = lk.writeLock();
try {
out.println("locked.. sleeping");
TimeUnit.SECONDS.sleep(5);
lk.unlock(stamp);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
答案 0 :(得分:2)
要明确的是,当争用增加时,StampedLock的读取速度会快得多。写作者要快一点,但不如读取速度快。我会解释原因。
大多数情况下,使用读写锁定,写入更少。但是,尽管如此,每次在readLock()
上获得ReentrantReadWriteLock
时,您都必须增加读者数量。这会强制使用此锁定在所有核心上进行高速缓存失效。
在严重争用下,这会导致读取时显着减慢。读取应该很快,在执行readLock()
时我们不应该更新变量,这是反直觉的。
相反,如果我们有印章或让我们说版本?每次读取迭代只更新一次的一个。
在竞争中,如果只有一个线程更新了一个戳记值(比如说在写入之后),那么这对我们的影响是,当想要读取锁定时,所有读取线程都将执行缓存命中。这会禁止缓存失效,并允许锁以比RRWL更合适的方式执行。
使用StampedLock
的模式类似于使用tryOptimisticRead
时的无锁算法(如CAS)