我有多个线程迭代列表。所有这些线程最终都会找到一个匹配元素,以便从列表中删除。
为了避免不一致的状态我应该为列表使用什么?向量?数组列表?其他
以下是使用Vectors的示例。它没有给出错误,但我确信它可以:
for(int i=0; i<timersVector.size(); i++){
currTimerThread = timersVector.get(i);
if(currTimerThread.getRowViewTag().equals(parent.getTag())){
currTimerThread.stopTimer();
timersVector.remove(i);
Log.i(tag, "timerVector size: "+timersVector.size());
}
}
例如,如果一个线程进入循环并且大小为10并且正好在另一个线程在5处移除元素之后,那么第一个线程会发生什么?
感谢您的帮助
答案 0 :(得分:5)
对于Vector,每个操作都是线程安全的,但不是多个操作。当您执行多个操作时,您需要在执行所有操作时锁定集合。即在这种情况下在循环之外。
e.g。你得到的元素(i)和你删除的元素(i)可以被另一个线程改变。无法保证您删除的元素是您选中的元素。
BTW ArrayList在1998年取代了Vector。我建议你使用它并根据需要进行同步和/或使用Collections.synchronizedList(new ArrayList<>())
答案 1 :(得分:1)
从多个线程访问列表需要synchronized List wrapper。 java.util.Collections实用程序类包含所有类型的同步包装器。
在你的情况下,使用这个简单的代码行包装你的列表(不要使用Vector,只有向后兼容):
List<Timer> timers = Collections.synchronizedList(originalTimers);
建议:在您的情况下使用同步地图会更有效,并且不需要循环来搜索项目。