在 while 循环之内或之外同步 ArrayList?

Synchronize ArrayList in or outside of while loop?

所以我有一个非常简单的案例:

while (resultSet.next())
{
    list.add(...);
}

我要同步列表。 (synchronized (list))

现在同步完整的 while 循环是不是更好?或者 synchronized 块应该在 while 循环内?

根据性能,当他必须在每个循环中锁定和释放列表时,是否存在相关差异?

主要区别在于,如果您在循环外锁定,则其他线程对列表的其他同步操作将不得不等待整个循环完成。

如果您只是在循环内同步,其他线程可以在插入之间修改列表。

所以正确的做法取决于您正在寻找的行为。

另外,请注意,您需要在所有其他地方同步列表,才能正常工作。如果其他线程在没有尝试获取锁的情况下修改列表,它们将能够这样做。

为防止这种情况发生,您可以使用已经提供线程安全的集合。

或者您可以像这样创建列表,而不用担心必须自己同步:

List aList = Collections.synchronizedList(new ArrayList());

最好将条目添加到没有其他线程正在访问的新列表,然后在完成从结果集中读取后将它们一起添加(使用 addAll)到共享 ArrayList .这样你就只需要同步一次,它会最大限度地减少与其他线程的争用,并且你不会在执行 I/O.

时持有锁
List localList = new ArrayList();
while (resultSet.next()) {
    localList.add(resultSet.get...);
}
synchronized(list) {
    list.addAll(localList);
}

理想情况下,您应该只同步特定的代码块,而不是整个循环。可以有一个单独的同步方法,可以从 while 循环中调用。这允许其他线程继续执行。如果您不执行任何昂贵的操作(如数据库更新),请尝试寻找替代方案,因为同步块会影响性能,因此始终建议谨慎使用它。