java - 可重入锁 VS 可重入读写锁

标签 java multithreading concurrency thread-safety

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

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

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;
  }
}

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

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();
    }
  }
}

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

最佳答案

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

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

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

关于java - 可重入锁 VS 可重入读写锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57809112/

相关文章:

java - 如何从 Java Applet 检测当前安全上下文

c# - Volatile Keyword 对非 C/C++ 背景有何作用?

c# - 这个线程安全吗?

ios - 发送 NSNotification 时,CustomCell 中的 UIProgressView 从不显示

java - RxJava - 调度程序与 ExecutorService?

java - JAX-WS 2.0 - 从 xsd :double to xsd:decimal 迁移

java - Android GradientDrawable setColor 不起作用

java - 每个选项卡的新 JVM 或进程

java - Phaser - 如何将其用作 CountDownLatch(1)?

java - 意外的多线程结果