创建大列表时,我遇到了一些奇怪的事情。我创建了子列表,因为整个列表太大。但是当检查结果大小时,我发现:
new ArrayList<>(rSet).size() != rSet.size();
其中rSet是HashSet
当我停止日食并进行调查时,我发现rSet有1000个项目,而对.size()的响应则更少(
less
项目的数量波动;有时rSet.size()
高于其实际包含的值)。我无法在单独的测试用例中重现它;该代码提供了太多的层。但是由单独的线程填充,这些线程在调用size
时结束。我说我是用线程填充的。我为所有线程提供
Set<> rSet
作为参数,并使用以下方法将新项目添加到集合中:public static void addSynchronized(final Set<?> c, final List<?> items) {
c.addAll(items);
}
我必须做一些代码不同意的事情……但是呢?
最佳答案
由单独的线程填充
我认为这是您的问题。 HashSet
不是线程安全的。从多个线程同时写入时,可能会发生任何事情。
要使其同步(来自docs):
Set s = Collections.synchronizedSet(new HashSet(...));
您的
addSynchronized
方法名称具有误导性,因为它不是synchronized
。 (具有一个名为list
的参数实际上是一个Set
也会引起混淆。)