我有一个列表,我迭代并执行一些操作。其中一个可以执行的操作可能导致工作被传递给另一个线程,这可能会在我的列表中添加更多元素,而我仍在第一个线程中迭代它。
我有没有办法以这样的方式遍历列表:迭代器包含来自其他线程的添加?
这是一些伪Java
Class1{
List multiThreadList = getMyList(); //points to list in Class2
for(Element element:multiThreadList)
//perform some actions, these actions may results in another thread being called
//which will cause addToMyList() to be called while I'm still iterating over it
//I want to keep iterating if an element gets added on the other thread
}
Class2{
List originalList = new ArrayList();
public getMyList()
return originalList;
void addToMyList(Element element)
originalList.add(element);
}
答案 0 :(得分:4)
你确定List是你需要的那种系列吗?
我会使用BlockingQueue,并在一个Thread中删除BlockingQueue中的元素,然后添加另一个。这样您就不需要任何额外的并发控制。
BlockingQueue<String> bounded = new LinkedBlockingQueue<String>();
bounded.put("Value");
String value = bounded.take();
您的伪代码变为
Class1{
BlockingQueue queue = getMyList();
Object element = queue.poll(0, TimeUnit.SECONDS);
while(element != null) {
//perform some actions, these actions may results in another thread being called
//which will cause addToMyList() to be called while I'm still iterating over it
//I want to keep iterating if an element gets added on the other thread
element = queue.poll(0, TimeUnit.SECONDS);
}
}
Class2{
BlockingQueue originalList = new LinkedBlockingQueue();
public BlockingQueue getMyList()
return originalList;
void addToMyList(Element element)
originalList.put(element);
}
但有一点,您需要了解,当前形式的此任务会给您带来不一致的结果。由于你没有控制另一个Thread,你的迭代器可能会在添加新元素之前完成,并且你会在迭代时错过它,这取决于你可以从零到所有新元素的系统状态。因此,您需要在完成迭代之前加入所有创建的线程,或者更改方法。
答案 1 :(得分:0)
您必须使用某种类型的并发控制机制,例如Mutex锁,信号量或监视器。这些创建了代码的“关键部分”,一次只允许一个线程访问它。
不幸的是,如果不以某种方式锁定代码并将其中的一部分串行化,则无法解决问题。