在 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 循环中调用。这允许其他线程继续执行。如果您不执行任何昂贵的操作(如数据库更新),请尝试寻找替代方案,因为同步块会影响性能,因此始终建议谨慎使用它。
所以我有一个非常简单的案例:
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 循环中调用。这允许其他线程继续执行。如果您不执行任何昂贵的操作(如数据库更新),请尝试寻找替代方案,因为同步块会影响性能,因此始终建议谨慎使用它。