我有一个单例标志(true/false),它将更改我的工作程序线程采用的代码路径。

public interface Flag {
  static Flag getSingleton() {
    // return LockedFlag.getFlag();
    return AtomicFlag.getFlag();
  }

  boolean isEnabled();
  void set(boolean isEnabled);
}

我的工作线程(数量很多)读取了该标志。一分钟内可以读取2000多次。我有一组不同的(非常少的)编写器线程来设置标志的值。每6个小时只有一次写入。

我想确保我的工作线程不会互相阻塞。另外,如果可能的话,我的作者会线程化以不阻止 worker 。

AtomicBoolean将为我完成这项工作还是ReadWriteLock更好地工作?
public class AtomicFlag implements Flag {
  private static AtomicFlag instance = new AtomicFlag();
  private AtomicBoolean flag;

  public static AtomicFlag getFlag() {return instance;}

  private AtomicFlag() {flag = new AtomicBoolean(false);}

  @Override
  public boolean isEnabled() {return flag.get();}

  @Override
  public void set(boolean isEnabled) {flag.set(isEnabled);}
}

或者
public class LockedFlag implements Flag {
  private static LockedFlag instance = new LockedFlag();
  private boolean flag;
  private ReadWriteLock lock;

  public static LockedFlag getFlag() {return instance;}

  private LockedFlag() {
    flag = false;
    lock = new ReentrantReadWriteLock();
  }

  @Override
  public boolean isEnabled() {
    lock.readLock().lock();
    try {return flag;} finally {lock.readLock().unlock();}
  }

  @Override
  public void set(boolean isEnabled) {
    lock.writeLock().lock();
    try {flag = isEnabled;} finally {lock.writeLock().unlock();}
  }
}

这两种实现之间有什么区别吗? -我对这些实现的幼稚尝试没有显示任何区别

没有比较和交换。它将永远是一个简单的集合。

最佳答案

我认为一定要有规模感。

如果执行的操作是每分钟2000x或每秒约30x,则大约每30毫秒执行一次。这意味着30 ms左右的任何操作都可能是一个问题。即如果两个线程每30 ms尝试将资源保留30 ms,则您遇到了问题。如果操作花费3毫秒,那么它们将以大约10%的时间互相干扰。如果线程更多,则资源争用的更改会增加。

这是一个以毫秒为单位的大概规模概念

 AtomicBoolean     0.000007 ms
 synchronized      0.000040 ms
 volatile boolean  0.000005 ms
 ReadWriteLock     0.000050 ms

现在您可能会说volatile boolean是最好的,因为它是最快的,但是,这些解决方案中的任何一个都比您需要的快得多,因此您应该选择最简单的解决方案,对我来说,它就是volatile boolean,尽管您可能更喜欢AtomicBoolean

关于java - Java:同时读取的效果更好-ReadWriteLock后面是AtomicBoolean还是boolean?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31577920/

10-11 22:13
查看更多