简体   繁体   English

具有嵌套 ArrayList 的对象的线程安全 HashMap

[英]Thread-safe HashMap of Objects with Nested ArrayList

I have a HashMap of objects with nested ArrayLists that is accessed by multiple threads.我有一个 HashMap 对象,其中包含多个线程可以访问的嵌套 ArrayLists。

I am wondering if declaring it as a synchronized HashMap is enough to make it thread-safe.我想知道将其声明为同步 HashMap 是否足以使其成为线程安全的。

public class ExampleRepository {

    private static Map<String, Example> examples = Collections.synchronizedMap(new HashMap<>());

    public static void addExample(Example example) {
        examples.put(example.getKey(), example);
    }

    public static Example getExample(String key) {
        return examples.get(key);
    }

}
public class Example {

    private String key;
    // More attributes
    private List<AnotherObject> anotherObjectList = new ArrayList<>();

    // Constructor

    public List<AnotherObject> getAnotherObjectList() {
        return anotherObjectList;
    }

    // More getters & Setters

}
public class Doer {

    // This function runs in an ExecutorService with many threads
    public static one(String key) {
        Example example = ExampleRepository.getExample(key);
        if (example != null) {
            // Do stuff
            example = new Example(values);
            AnotherObject anotherObject = new AnotherObject(values);
            example.getAnotherObjectList().add(anotherObject);
            ExampleRepository.addExample(example);
        }
        two(example);
    }

    private static two(Example example) {
        // Do stuff
        AnotherObject anotherObject = new AnotherObject(values);
        trim(example.getAnotherObjectList(), time);
        example.getAnotherObjectList().add(anotherObject);
    }

     private static void trim(List<AnotherObject> anotherObjectList, int time) {
        short counter = 0;
        for (AnotherObject anotherObject : anotherObjectList) {
            if (anotherObject.getTime() < time - ONE_HOUR) {
                counter++;
            } else {
                break;
            }
        }
        if (counter > 0) {
            anotherObjectList.subList(0, counter).clear();
        }
    }

}

I guess the question is adding Example objects to the HashMap thread safe?我想问题是将示例对象添加到 HashMap 线程安全吗? Also, is removing and adding AnotherObject objects to the nested list thread-safe or should I declared it as synchronized ArrayList?此外,将 AnotherObject 对象删除和添加到嵌套列表线程安全还是应该将其声明为同步 ArrayList?

I would greatly appreciate any insights.我将不胜感激任何见解。 Thank you very much!非常感谢!

Thank you very much for the answers.非常感谢您的回答。 I just realized that I actually loop a little over the nested AnotherObject.我刚刚意识到我实际上在嵌套的 AnotherObject 上循环了一点。 If i make the ArrayList a synchronized ArrayList, should I still put it in a synchronized block?如果我将 ArrayList 设为同步 ArrayList,我还应该将它放在同步块中吗?

Thank you again!再次感谢你!

I guess the question is adding Example objects to the HashMap thread safe?我想问题是将示例对象添加到 HashMap 线程安全吗?

-> Yes putting Example object to map is thread-safe. -> 是的,将示例 object 放到 map 是线程安全的。

Also, is removing and adding AnotherObjet objects to the nested list thread-safe or should I declared it as synchronized ArrayList?此外,将 AnotherObjet 对象删除和添加到嵌套列表线程安全还是应该将其声明为同步 ArrayList?

-> Removing objects from the list does not guarantee that it will be thread-safe. -> 从列表中删除对象并不能保证它是线程安全的。

Any operation on the map will be thread-safe as you have used the Synchronized map. map 上的任何操作都将是线程安全的,因为您使用了同步 map。 ArrayList in Example object will be still unsafe to thread.示例 object 中的 ArrayList 仍然对线程不安全。

Thread-safe in a collection/map does not mean it will make API of any/every object it contains thread-safe.集合/映射中的线程安全并不意味着它将使其包含的任何/每个 object 的 API 成为线程安全的。

The thing you have to be clear about is what you mean by "thread safe".您必须清楚的是“线程安全”的含义。

I guess the question is adding Example objects to the HashMap thread safe?我想问题是将示例对象添加到 HashMap 线程安全吗?

Making the map synchronized guarantees that the structural modifications you make to the map are visible to all threads.使 map 同步可确保您对 map 所做的结构修改对所有线程都是可见的。

Also, is removing and adding AnotherObjet objects to the nested list thread-safe or should I declared it as synchronized ArrayList?此外,将 AnotherObjet 对象删除和添加到嵌套列表线程安全还是应该将其声明为同步 ArrayList?

No: you would need to externally synchronize accesses to the lists if you want structural modifications to the lists to be visible in all threads.否:如果您希望对列表的结构修改在所有线程中可见,则需要在外部同步对列表的访问。

That could mean using synchronizedList , but you could "manually" synchronize on the list, or even on the map (or one of a number of other ways that create happens-before guarantees).这可能意味着使用synchronizedList ,但您可以“手动”在列表上同步,甚至在 map 上(或创建发生前发生保证的多种其他方式之一)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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