为什么Java StampedLock比ReentrantReadWriteLock快

问题描述 投票:3回答:1

comparison of StampedLock and other locks表明,随着竞争的加剧,StampedLock最快。但是,本文以及其他各种文章都没有列出为什么它更快。似乎使用与其他类型的锁相同的CAS语义?谁能解释为什么随着争用的增加它最快?例如,在下面的代码中,writeLock不仅阻止其他writeLock,还阻止readLock。我现在不关心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();

}
java multithreading nonblocking
1个回答
2
投票

要清楚,当争用增加时,StampedLock在读取时要快得多。编写器速度稍快一些,但不及读取速度快。我会解释原因。

在大多数情况下,使用读写锁时,写入的方式会更少。但是,尽管如此,每当您在readLock()上获取ReentrantReadWriteLock时,都必须增加读取器计数。这会在使用此锁的所有内核上强制缓存无效。

在激烈的争用下,这可能会导致读取时显着降低速度。读取应该很快,当执行readLock()时,我们不必更新变量,这很直观。

如果相反,我们有图章,或者说是版本,该怎么办?每个读取迭代仅更新一次的程序。

这对我们的作用是,在争用中,如果只有一个线程更新标记值(比如说在写之后),那么当想要在锁上进行读取时,所有读取线程将执行高速缓存命中。这禁止了缓存无效,并允许以比RRWL更合适的方式执行锁定。

[使用StampedLock的模式类似于使用tryOptimisticRead时的无锁算法(如CAS)

  1. 获得邮票
  2. 读取值
  3. 邮票是否已更改?
    • 是,请重试或发出阻止阅读
    • 不,我们很好,让我们继续前进。
© www.soinside.com 2019 - 2024. All rights reserved.