我想这么做:
在此过程中,我希望其他线程等待,直到完成。因此,我需要在线程上放置一个读锁,并在逻辑完成后释放锁。
以下是我的尝试:
AtomicReference<String> version = new AtomicReference<>();
String v = version.get(); // Is there way to put a read lock here so that when other thread try to read it, they will have to wait until the current thread finish
if (v.equals("old")) {
String newVersion = getNewVersion(); // execute a complex logic
version.set(newVersion);
}
// release the lock here发布于 2020-10-29 14:59:38
像这样阻塞所有读取线程(通过get)是不可能的。为此,您需要使用其他工具,并且需要在使用version的任何地方使用它们。
与您的想法最接近的是使用AtomicReference的原子方法,比如updateAndGet
AtomicReference<String> version = new AtomicReference<>();
version.updateAndGet(v -> {
if (v.equals("old")) {
return getNewVersion();
}
else {
return v;
}
});这种方法的一个简单实现是:
public T updateAndGet(UnaryOperator<T> f) {
T curr, next;
do {
curr = get();
next = f.apply(curr);
} while (!compareAndSet(curr, next));
return next;
}如果第一个给定的参数等于实际的当前值,则方法compareAndSet (即访问底层CAS指令的外观)返回true,否则为false。如果第一个给定的参数等于实际的当前值,则用第二个参数(比较和交换)替换当前值。
现在我为什么要解释这个?因为使用updateAndGet很接近您想要的,但不同的是:
getNewVersion一次运行更多。当在curr = get();和CAS调用之间的另一个线程更改当前值时,就会发生这种情况。curr = get();和CAS调用之间进行的读取将得到旧值,而不是像您的想法中那样的新值。但是这个时间段很小,你不应该担心它。AtomicXXX类的最大好处之一。你想让它们轻巧快速。https://stackoverflow.com/questions/64593262
复制相似问题