java - 多线程处理 - java等待线程完成

我有一个线程下载数据,我想等到下载完成后,再加载数据。有什么标准的方法来做这个?

更多信息:

我有一个从URL(序列化POJO)获取数据的下载类。下载是可运行和可观察的,它跟踪下载的字节和下载大小,我有一个进度栏,显示了用户的进度,GUI观察下载以更新进度条。

下载POJO时我想得到它并转到下一步。每一步都必须等待上一次完成,问题是我想不出暂停我的应用程序等待下载线程的方法,下载完成后,我想调用download.getObject(),它将返回作为对象的数据,然后我可以取得它,并且继续下一次下载。

非常感谢你。

时间:

你可以从java.util.concurrent包中使用CountDownLatch ,在等待线程继续执行之前,等待一个或多个线程完成是非常有用的。

例如等待三个任务完成:

 

CountDownLatch latch = new CountDownLatch(3);


...


latch.await();//Wait for countdown



另一个线程在完成任务后,每次调用latch.countDown() ,一旦倒计时完成,在这个例子中,执行将会继续。

SwingWorker具有可用于执行任务的doInBackground() ,你可以选择调用get(),并且等待下载完成,或者在 SwingWorker完成后,重写将调用的done()方法。

Swingworker对您当前的方法有优势,因为它具有您正在寻找的许多功能,因此无需重新发明轮子。你可以使用getProgress()setProgress()方法作为可以下载进度的观察器的观察者替代方法,在工作完成后,我们将在上述工作中调用done()方法,这允许你在下载完成后,加载数据。

ExecutorService.html#invokeAll是一种替代方案。

执行给定的任务,返回完成所有状态和结果的Futures列表。Future.isDone()对于返回列表的每个元素都是true 。

注意,完成的任务可以正常终止,也可以引发异常,此方法的结果是未定义的,如果在执行这个操作时修改了给定的Collection,则。

为实现相同目的, ForkJoinPoolExecutors.html#newWorkStealingPool提供了其他。

示例代码Fragment:

 

import java.util.concurrent.*;



import java.util.*;



public class InvokeAllDemo{


 public InvokeAllDemo(){


 System.out.println(" creating service" );


 ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());



 List<MyCallable> futureList = new ArrayList<MyCallable>();


 for ( int i=0; i<10; i++){


 MyCallable myCallable = new MyCallable((long)i);


 futureList.add(myCallable);


 }


 System.out.println(" Start" );


 try{


 List<Future<Long>> futures = service.invokeAll(futureList); 


 }catch(Exception err){


 err.printStackTrace();


 }


 System.out.println(" Completed" );


 service.shutdown();


 }


 public static void main(String args[]){


 InvokeAllDemo demo = new InvokeAllDemo();


 }


 class MyCallable implements Callable<Long>{


 Long id = 0L;


 public MyCallable(Long val){


 this.id = val;


 }


 public Long call(){


 //Add your business logic


 return id;


 }


 }


}



通常,当希望等待线程完成时,应该调用 join() 。

你可以使用join()等待所有线程完成,创建线程时保留全局ArrayList中的所有线程,之后,将它保持在如下循环中:

 

for (int i = 0; i <10; i++) 


{


 Thread T1 = new Thread(new ThreadTest(i)); 


 T1.start(); 


 arrThreads.add(T1);


} 



for (int i = 0; i <arrThreads.size(); i++) 


{


 arrThreads.get(i).join(); 


}



在这里查看完整的详细信息: http://www.letmeknows.com/2017/04/24/wait-for-threads-to-finish-java

...