我是Java并发的新手,我有一个类保存数据(下面的示例代码中有两个),应该使用get(如Map)访问,但出于性能原因,内部存储在数组中的数据。 / p>
这在多线程环境中运行,有时必须更新此索引。
public class ConcurrencySampleCode {
private static Object lock = new Object();
private Map<String, Integer> map = ...
private double[] array = ...
public Double get(String id) {
synchronized (lock) {
Integer i = map.get(id);
if (i == null) {
return null;
}
return array[i];
}
}
public void update() {
Map<String, Integer> tmpMap = updateMap(...);
double[] tmpArray = updateArray(...);
synchronized (lock) { // should be atomic
map = tmpMap;
array = tmpArray;
}
}
}
我不确定这段代码是否正确?此外,get函数中是否需要synchronized关键字?
有更好的方法吗?
感谢您的帮助
答案 0 :(得分:1)
您的代码没有任何问题,但您需要在地图和数组中使用volatile关键字,以确保所有线程立即看到更新的值,而我不是确定你想要锁是静态的。
作为替代方案,您可能需要查看java.util.concurrent.atomic包。它有一些方便的线程安全变量。例如,您可以将地图和数组移动到自己的类中,然后使用AtomicReference存储对象。
public class ConcurrencySampleCode {
private AtomicReference<DoubleMap> atomicMap = new AtomicReference(new DoubleMap());
//Inner class used to hold the map and array pair
public class DoubleMap {
private Map<String, Integer> map = ...
private double[] array = ...
}
public Double get(String id) {
DoubleMap map = atomicMap.get();
...
}
public void update() {
Map<String, Integer> tmpMap = updateMap(...);
double[] tmpArray = updateArray(...);
DoubleMap newMap = new DoubleMap(tmpMap, tmpArray);
atomicMap.set(newMap);
}
}
答案 1 :(得分:0)
并发编程中有很多事情发生,但例如你的update()
方法有问题。在当前状态下,多个Threads
可以调用ConcurrencySampleCode.update()
,并且每个人都会在同步开始之前在身体内发起update
个调用。这意味着在循环周转之后更新调用的最后一个Thread
将不会更新新更新的地图和数组中之前的update
次调用。
长篇故事,尝试使用并理解ConcurrentHashMap