2012-02-28 34 views
0

我在单独的线程中同时下载几个图像。我需要将这些图像设置为适配器。我需要按照它们开始的顺序完成这些线程,因为我使用回调函数来通知适配器,并且....我如何执行此操作(按照启动顺序完成线程)?完成线程在它们开始的顺序

回答

0

以特定顺序完成您的线程与多线程编程思想相反......您不想启动线程1,2和3,然后在完成时指定它们,因为它们可能有完成时间完全不同的任务。

例如,如果您要在两个不同的线程上下载两个不同的东西,如果线程1正在下载一个2TB的文件而线程2正在下载一个2KB的文件呢?很明显,线程2将在线程1之前完成,并且您不希望进程必须阻止等待线程1完成...我建议重新考虑您正在尝试完成的任务并相应地进行重新设计,以避免这个。

1

你可以写一个类说Mediator,将类的相同实例传递给所有线程。当线程完成下载时,他们会通过调用一些方法来通知中介者,比如说downloadComplete(线程ID),中介将跟踪订购这些线程并回调。

0

按顺序完成线程可能不是你真正想要的 - 这将是一个相当人造的构造。我认为你可能真正想要的是一个所谓的障碍,这意味着让线程运行,然后等待所有线程完成。之后,您可以调用一些代码(可能来自您的主线程)以按您需要的顺序处理结果。为了等待所有线程完成,只需调用join()上所有的人,像下面(的错误处理跳过清晰度):

//Create and start workers asynchronously 
Thread[] workers = new Thread[NUM]; 
for (int i = 0; i < workers.length; i++) { 
    workers[i] = new MyWorkerThread(dataSlice[i]); 
    workers[i].start(); 
} 
//Barrier - wait till all threads are done 
for (int i = 0; i < workers.length; i++) { 
    workers[i].join(); 
} 
//Loop over generated results in some order, here reversed order just for fun 
for (int i = workers.length; i > 0; i--) { 
    soSomething(dataSlice[i]); 
} 
1

听起来像是你可能不一定在乎的顺序哪些任务完成,而您想要控制处理结果的顺序。

如果您将Runnable提交给ExecutorService,您将返回一个Future对象。然后,您可以使用Future对象的#get()方法http://developer.android.com/reference/java/util/concurrent/Future.html#get(),按顺序等待每个线程的结果。

如果使用AsyncTask执行每个线程,则可以使用AsyncTask的#get()方法,而不是http://developer.android.com/reference/android/os/AsyncTask.html#get()。

下面是一个代码示例:

int time = nbrOfThreads; 

List<AsyncTask<Integer, Void, Integer>> tasks = new ArrayList<AsyncTask<Integer, Void, Integer>>(); 
for (int i = 0; i < nbrOfThreads; i++) { 
    final int threadNumber = i; 

    AsyncTask<Integer, Void, Integer> task = new AsyncTask<Integer, Void, Integer>() { 

     @Override 
     protected Integer doInBackground(Integer... secondsToSleep) { 
      try { 
       Thread.sleep(secondsToSleep[0] * 1000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      return threadNumber; 
     } 
    }; 

    tasks.add(i, task); 
    task.execute(time--); 
} 

for (AsyncTask<Integer, Void, Integer> task : tasks) { 
    print("Thread number: " + task.get() + " completed."); 
}