我有一个包含嵌套 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/