我正在构建一个Android应用程序,我对这个体系结构有一些问题--如何在不同的线程上实现许多调用。
我有两种方法:
ConnectAndGetId() //takes 2-3 seconds
GetTokenID(ID) //takes 2-3 seconds首先,我需要调用ConnectAndGetId(),然后在得到一个结果之后,ID调用GetTokenID(ID)。获得tokenID后,我需要调用4个方法并传递给它们tokenID
getNames (tokenID) //takes 4 second
getPhones (tokenID) //takes 7 seconds
getIds(tokenID) //takes 2 seconds
getDetailObject(tokenID) //takes 5 seconds这样做的目的是在得到来自的ALL 4方法的结果之后,只显示数据。不需要一个一个地执行它们,因为这将花费大量的时间(18秒),我想并行地运行它们,最后用所有的数据来更新UI。
我想做下一件事:
启动AsyncTask并调用ConnectAndGetId,在onPostExecute()中启动另一个AsyncTask并在那里运行GetTokenID(ID)。在运行GetTokenID(ID)之后,我将将结果返回给UI线程,使用返回的数据,我将启动4个新的threads,每个线程将调用这4个方法中的一个。我可以计数完成的线程,当我得到所有的4个结果时,我可以用处理程序更新UI。
这是正确的做法吗?也许我不应该为4个方法创建4个线程?否则,创建一个handlerThread并将这4个方法传递给他的处理程序,这样线程就会将它们集中起来--但它将是一个接一个的。
这是正确的想法还是可以做得更好?
发布于 2014-07-23 09:11:26
这是正常的方法。但是我建议您使用Executor,而不是创建Threads。示例:
public class TasksSample {
public static void execute(){
ExecutorService executorService = Executors.newFixedThreadPool(4);
executorService.submit(new Task("A"));
executorService.submit(new Task("B"));
executorService.submit(new Task("C"));
executorService.submit(new Task("D"));
executorService.shutdown();
try {
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("all tasks finished");
}
private static class Task implements Runnable{
private String taskId;
public Task(String taskId) {
this.taskId = taskId;
}
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("finished task: " + taskId);
}
}
}发布于 2014-07-23 09:01:15
问题确实很好。我认为您的方法是正确的,但是我不会在onPostExecute()上创建onPostExecute线程。我认为最好是用一个听众来确保你得到了你所需要的结果。在接下来的步骤中,我还将使用一个监听器来调用您的4个方法。
问题是:您是否需要完成这4种方法来更新您的UI?然后,您应该使用一个具有同步块的监听器,该监听器只在4个方法完成时才输入。您可以使用一种方法来检查这些方法是否得到了它们的结果,并且当4完成时,更新UI。
如果您不需要完成更新UI的4个方法,我只需在UI中添加一个ProgressDialog并逐个方法更新它。在最后一个中,取消ProgressDialog并解除UI的阻塞。
我希望它能帮助你,兄弟,祝你在编码方面好运!
发布于 2014-07-23 09:24:42
关于运行四个线程是否适合您的情况,只有您可以判断。它增加了程序的复杂性,需要多线程访问保护和相关数据的同步。还要考虑并行访问是否真的可以加快计算速度。只有当限制因素是单线程计算速度时,并行访问才会加快,如果限制是以数据带宽为限,您将不会看到任何显著的速度增长。
对于四个线程完成一个UI更新的问题,您可以尝试使用CyclicBarrier锁定所有线程,直到最后一个线程完成执行为止。
以下是一个示例:
// Create a CyclicBarrier with 4 parties and a target action to update UI
CyclicBarrier barrier = new CyclicBarrier(4, new Runnable(){
public void run(){
//Do your UI updates here (remember any direct UI must be on UI thread)
}
});
// Pass above CyclicBarrier to your four threads
// Skeleton of Runnable instance for each of the four threads.
Runnable r = new Runnable(){
public void run(){
// Run desired long-running method
// getNames, getPhones, etc
// Call await() from CyclicBarrier instance (exception handling not shown)
barrier.await();
}
};使用上面的代码,完成的每个线程都将阻塞等待方法,直到第四个线程调用await()为止,在第四个线程中,所有线程取消阻塞,最后一个线程运行在开始时传递给CyclicBarrier的可运行线程。
https://stackoverflow.com/questions/24905981
复制相似问题