所以我有一个非常简单的案例:
while (resultSet.next())
{
list.add(...);
}
我想要同步列表。 (synchronized (list)
)
现在最好同步完整的while循环吗?或者同步块是否应该在while循环中?
当他必须在每个循环中锁定并释放列表时,取决于性能,是否存在相关差异?
答案 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更新),请尝试寻找替代方案,因为同步块会影响性能,因此始终建议您小心使用它。