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

标签 java multithreading object arraylist hashmap

我有一个包含嵌套 ArrayList 的对象的 HashMap,可供多个线程访问。

我想知道将其声明为同步 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();
        }
    }

}

我猜问题是将Example对象添加到HashMap线程安全?另外,删除 AnotherObject 对象并将其添加到嵌套列表中是线程安全的还是应该将其声明为同步 ArrayList?

如果有任何见解,我将不胜感激。非常感谢!

非常感谢您的回答。我刚刚意识到我实际上在嵌套的 AnotherObject 上循环了一点。如果我将 ArrayList 设为同步 ArrayList,我还应该将其放在同步块(synchronized block)中吗?

再次感谢您!

最佳答案

您必须清楚“线程安全”的含义。

I guess the question is adding Example objects to the HashMap thread safe?

使映射同步可保证您对映射所做的结构修改对所有线程都可见。

Also, is removing and adding AnotherObjet objects to the nested list thread-safe or should I declared it as synchronized ArrayList?

否:如果您希望对列表的结构修改在所有线程中可见,则需要从外部同步对列表的访问。

这可能意味着使用synchronizedList,但您可以“手动”在列表上同步,甚至在 map 上同步(或创建发生前保证的多种其他方式之一)。

关于java - 具有嵌套 ArrayList 的对象的线程安全 HashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58564181/

相关文章:

java - 无法建立安全连接,因为此站点使用不受支持的协议(protocol)

java - 对象 == null 与 boolean == false

java - 使用 Rest Assured 发出 POST 请求时出现内部服务器错误

java - 如何在 Spring Boot 单元测试中模拟 JWT 身份验证?

java - 来自另一个类的 Android Interface 类显示空指针异常

javascript - 定义 Javascript 对象的 'implied' 方法

javascript - 将 HTML 表格(作为字符串)转换为 JS 对象数组

multithreading - 在 Clojure 的多线程程序中初始化资源的正确方法是什么

c# - 任务(或线程)需要 Wait 或 Join 才能工作

java - 使用 JADE 和 Excel 的问题