繁体   English   中英

java-并发更新多个对象

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM