Vector是同步的,ArrayList不是同步的,但是我们可以通过Collections.synchronizedList(aList)
同步一个ArrayList,这样会更好更快地执行吗?
答案 0 :(得分:3)
同步收藏是浪费时间和危险的。一个简单的例子,为什么它们是坏的是考虑在同一个集合上同时运行一个循环的两个线程:
int i = 0;
while (i < list.size())
{
if (testSomeCondition(list.get())) {
list.remove(i);
else
i++;
}
我们的列表可以同步(例如Vector),这段代码仍然可以破解。为什么?因为对size(),get(),remove()的单独调用是同步的,但是一个线程仍然可以从列表中删除项目而另一个正在迭代它。换句话说,我们有竞争条件,同步集合的使用并没有给我们带来任何好处。
要修复竞争,我们必须同步集合上的整个操作,或者使用Java 5并发锁来执行相同的操作。
synchronized (list) {
int i = 0;
while (i < list.size())
{
if (testSomeCondition(list.get())) {
list.remove(i);
else
i++;
}
}
这段代码现在是线程安全的,因为一次只有一个线程可以执行循环。现在没有理由使用同步集合。我们可以使用ArrayList而不是Vector来节省所有这些同步调用的性能损失。
所以不要使用同步集合。如果您发现自己有多个线程命中同一个列表,那么您需要保护列表中的操作,而不是单个调用。