可重入锁 VS 可重入读写锁

jok*_*ker 10 java concurrency multithreading thread-safety

ReentrantLock我想知道和 之间ReentrantReadWriteLock在逻辑差异方面有什么区别。换句话说,是否存在只需要一个锁而不需要读/写锁的情况,反之亦然,读/写锁和仅一个锁是不够的?

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

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

考虑以下读/写锁示例,并将其与上一个进行比较:

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();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

小智 3

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

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

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