这个StampedLock锁与其他锁的比较显示,随着争用的增加,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();
}发布于 2017-05-02 15:17:35
要明确的是,当争用上升时,StampedLock在读取方面要快得多。作家的速度有点快,但没有读得快。我会解释原因。
大多数情况下,使用读写锁的情况下,写的次数要少得多。然而,尽管如此,每次在readLock()上获得ReentrantReadWriteLock时,都必须增加一个读取器计数。这将强制使用此锁的所有内核上的缓存失效。
在严重争用的情况下,这可能会导致读取时明显的慢下来。读取应该是快速的,在执行readLock()时我们不需要更新变量,这是违反直觉的。
如果,我们有邮票,或者说,版本呢?每次读取迭代只更新一次的人。
这对我们所做的是,在争用中,如果只有一个线程更新一个邮票值(例如在写完之后),那么所有读取线程在希望在锁上读取时都会执行缓存命中。这将禁止缓存失效,并允许以比RRWL更合适的方式执行锁。
使用StampedLock的模式类似于使用tryOptimisticRead时的无锁算法(如CAS)。
https://stackoverflow.com/questions/43723900
复制相似问题