创建大列表时,我遇到了一些奇怪的事情。我创建了子列表,因为整个列表太大。但是当检查结果大小时,我发现:

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也会引起混淆。)

10-08 19:43