[英]java - concurrent updates to multiple objects
我是Java并发的新手,我有一个类,该类包含一个数据(在下面的示例代码中为双精度),应该使用get(如Map)进行访问,但是出于性能方面的考虑,这些数据会内部存储在数组中。
它在多线程环境中运行,并且有时必须更新此索引。
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函数中是否需要synced关键字?
有更好的方法吗?
谢谢你的帮助
您的代码没有错,但是您将需要在地图和数组上使用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);
}
}
并发编程中发生了很多事情,但是例如您的update()
方法有问题。 在当前状态下,多个Threads
可以调用ConcurrencySampleCode.update()
并且它们中的每个Threads
都将在同步开始之前在体内启动两个update
调用。这意味着在循环更新之后,具有更新调用的最后一个Thread
将在新的更新映射和数组中没有与先前update
调用的更改。
长话短说,尝试使用和了解ConcurrentHashMap
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.