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

时间:2015-09-08 13:34:25

标签: java multithreading performance while-loop synchronized

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

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

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

现在最好同步完整的while循环吗?或者同步块是否应该在while循环中?

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

3 个答案:

答案 0 :(得分:1)

最好将条目添加到其他线程无法访问的新列表中,然后在读完resultSet后将它们全部(使用addAll)一起添加到共享ArrayList中。这样你只需要同步一次,它可以最大限度地减少与其他线程的争用,并且在执行I / O时你不会持有锁。

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

答案 1 :(得分:0)

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

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

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

此外,请注意您需要在所有其他位置的列表上同步才能使其正常工作。如果其他线程修改了列表而没有尝试获取锁定,那么他们就可以这样做。

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

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

DataAdapter

答案 2 :(得分:0)

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