如何将项目添加到线程列表中并保持添加顺序?
我试图在列表中添加一些项目并保留添加顺序。问题是 的添加部分是在一个线程中完成的,因为我需要从DB获得一些细节,将它们放在
项目中并将其添加到列表中。如何将项目添加到线程列表中并保持添加顺序?
public void addNewItem(Step item){
Thread t = new Thread(new Runnable(){
public void run() {
item.setDetails(db.getStepDetails(step.getId()));
add(item);
}
});
t.start();
}
的add
方法是这样的:
private void add(Step step){
mitems.add(step);
}
如果我这样做
addNewItem(stepA);
addNewItem(stepB);
如果第一次调用花费太多时间,第二项是第一次在我的名单中添加。
您是否知道在我的列表中继续添加任何其他项目之前,我该如何等待某个操作完成?
谢谢。
您可以添加同步块或使用ReentrantLock。
Thread t = new Thread(new Runnable(){
public void run() {
synchronized(someSafeVar) {
item.setDetails(db.getStepDetails(step.getId()));
add(item);
}
}
});
此外,如果只是需要时间的“添加”方法,则此方法只能同步。
如果您将物品添加到清单之前您设置的详细信息,您可以保留您的物品订单。 那么你可以用随后的所有操作等到你的项目的初始化标志设置:
mitems.add(stepA);
mitems.add(stepB)
[...]
ThreadGroup group = new ThreadGroup("GetStepDetailsGroup");
for(Step step : mitems)
{
Thread thread = new Thread(group, new Runnable(){
public void run() {
item.setDetails(db.getStepDetails(step.getId()));
}
});
thread.start();
}
while(group.activeCount() > 0) {
try {
Thread.sleep(50);
} catch(InteruptedExpection e) {
// ignored
}
}
您可以创建一个工作线程,并从队列中喂养它,这样的话你将有一个单独的线程加入到mitems。
您需要在这种情况下创建两个列表,并同步它们。
EG,
List<Step> processingList = new ArrayList<Step>();
List<Step> mitems = new ArrayList<Step>();
public void addNewItem(Step item)
{
syncrhonized(processingList)
{
processingList.add(item);
}
}
工作者线程需要的物品从processingList的前面,适用于他们,并将他们时,他们已经准备好mitems。
我建议使用队列
你可以使用一个字典来代替:
Dictionary mitems = new Hashtable();
和
mitems.put("1", item);
的关键将是命令即可。
在您的示例中,它看起来像将列表中的步骤添加到完全独立于从数据库检索信息并填写步骤。
因此,您可以只使用一个线程将所有步骤放入列表中。然后,您可以使用Runnables获取数据库信息,每个步骤一个,并在Executor中执行这些Runnable,并使用尽可能多的线程(同时仍然从多线程获得加速)。
我可能是错的,但我相信使用'synchronize'可以解决这个问题 – codeMagic 2013-04-11 12:44:13
你真的想用一个单独的线程?在你的情况下,你需要按顺序执行指令。 – blint 2013-04-11 12:46:11
解决方法是一个同步的ID,每次添加时都会增加并存储在添加的项目中。然后,您可以在结果容器中看到添加项目的顺序。 – TheBlastOne 2013-04-11 12:46:29