Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/201.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从线程向列表中添加项目并保持添加顺序?_Java_Android_Multithreading - Fatal编程技术网

Java 如何从线程向列表中添加项目并保持添加顺序?

Java 如何从线程向列表中添加项目并保持添加顺序?,java,android,multithreading,Java,Android,Multithreading,我试图在列表中添加一些项目,并保持添加顺序。问题是 添加部分是在一个线程中完成的,因为我需要从DB获取一些详细信息,将它们放在一个 项目并将其添加到列表中 public void addNewItem(Step item){ Thread t = new Thread(new Runnable(){ public void run() { item.setDetails(db.getStepDetails(step.getId()));

我试图在列表中添加一些项目,并保持添加顺序。问题是 添加部分是在一个线程中完成的,因为我需要从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中

在这种情况下,您需要创建两个列表,并同步它们

例如

List processingList=new ArrayList();
List mitems=new ArrayList();
公共无效addNewItem(步骤项)
{
同步化(处理列表)
{
处理列表。添加(项);
}
}

工作线程从processingList前面获取项目,对其进行处理,并在项目准备就绪时将其添加到mitems中。

您可以使用字典来代替:

Dictionary mitems = new Hashtable();


关键是顺序。

在您的示例中,似乎将步骤添加到列表完全独立于从数据库检索信息和填充步骤

因此,您可以只使用一个线程将所有步骤放在一个列表中。然后,您将使用Runnables获取DB信息,每个步骤一个Runnables,并在执行器中使用任意多个线程执行这些Runnables(同时仍然可以从多线程中获得加速)。

等待此线程死亡

希望这有帮助,
Yaron

我可能错了,但我相信使用
同步
可以解决这个问题。你真的想使用单独的线程吗?在您的情况下,您需要按顺序执行指令。解决方法是在每次添加时增加同步id,并将其存储在添加的项中。然后,您可以在结果容器中看到项目的添加顺序
Dictionary mitems = new Hashtable();
mitems.put("1", item);