我有一个单例标志(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/