首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ReentrantLock VS ReentrantReadWriteLock

ReentrantLock VS ReentrantReadWriteLock
EN

Stack Overflow用户
提问于 2019-09-05 23:53:11
回答 2查看 3K关注 0票数 4

我想知道ReentrantLockReentrantReadWriteLock在逻辑上有什么不同。换句话说,是否存在只需要一个没有读/写锁的锁的情况,反之亦然,读/写锁和只有一个锁是不够的?

考虑以下仅使用锁的主要示例:

代码语言:javascript
复制
public class Counter {

  private int counter = 0;
  private ReentrantLock lock = new ReentrantLock(true);

  public void increment() {
    lock.lock();
    counter += 1;
    lock.unlock();
  }

  public int getCounter() {
    return counter;
  }
}

考虑下面的读写锁示例,并将其与前面的示例进行比较:

代码语言:javascript
复制
public class Counter {

  private int counter = 0;
  private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);

  public void increment() {
    lock.writeLock().lock();
    try {
      counter += 1;
    } finally {
      lock.writeLock().unlock();
    }
  }

  public int getCounter() {
    lock.readLock().lock();
    try {
      return counter;
    } finally {
      lock.readLock().unlock();
    }
  }
}

就线程安全性而言,这两个选项中哪一个是正确的实现?为什么?

EN

回答 2

Stack Overflow用户

发布于 2019-09-06 00:19:03

使用ReentrantLockReentrantReadWriteLock取决于您想要解决的用例。

在您的第一个示例中,getCounter()方法没有锁。因此,当线程在增量方法中保存ReentrantLock时,获取计数器是可能的。

在您的第二个示例中,当线程在增量方法中持有writeLock()时,您无法获取计数器。并且保持readLock()可以防止计数器递增。读取你的counter参数的几个线程可能同时持有readLock()

票数 2
EN

Stack Overflow用户

发布于 2019-09-08 11:18:36

当读操作多于写操作时,通过仔细控制AbstractQueuedSynchronizer$stateReentrantReadWriteLock可以提供更高的性能。

如果不是,则控制开销比ReentrantLock更高。

对于您的第一个示例,您不需要考虑getCounter()方法的原子性问题是正确的,但是应该考虑可见性问题。即使其他线程已经递增了计数器,一个线程也可以看到初始值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57809112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档