Java,从多个线程中删除元素

时间:2014-06-26 16:41:51

标签: java collections thread-safety

我有多个线程迭代列表。所有这些线程最终都会找到一个匹配元素,以便从列表中删除。

为了避免不一致的状态我应该为列表使用什么?向量?数组列表?其他

以下是使用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处移除元素之后,那么第一个线程会发生什么?

感谢您的帮助

2 个答案:

答案 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);

建议:在您的情况下使用同步地图会更有效,并且不需要循环来搜索项目。