我有一个线程下载数据,我想等到下载完成后再加载数据。有没有一种标准的方法呢?
更多信息:
我有一个从URL(序列化POJO)获取数据的Download类。下载是Runnable和Observable。它跟踪下载的字节数和下载大小。我有一个进度条,向用户显示进度。 GUI观察下载以更新进度条。
当下载POJO时,我想得到它并转到下一步。每一步都必须等待前一步完成。问题是我想不出一种暂停我的应用程序等待下载线程的方法。下载完成后,我想调用download.getObject(),它将数据作为对象返回。然后我可以投下它并继续下载。
我有一个帮助程序类来管理要下载的URL,并进行所有下载调用。此调用将调用getObject并执行转换。 Gui调用helper.getUser()。帮助程序启动线程运行,我希望它在完成时“知道”,以便它可以返回已转换的对象。
有什么建议/例子吗?我处于这个设计的开始阶段,所以我愿意改变它。
谢天谢地。
更新
我跟着http://download.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html#get并使用模态来阻止,直到线程结束。代码非常混乱,我不喜欢这种方法。我将继续尝试找到一种“干净”的方式来处理下载过程的工作流程。
答案 0 :(得分:64)
Thread
有一个为你做join的方法,它将阻塞直到线程完成执行。
答案 1 :(得分:49)
您可以使用CountDownLatch
包中的java.util.concurrent
。在等待一个或多个线程完成之前,它在等待线程中继续执行之前非常有用。
例如,等待完成三个任务:
CountDownLatch latch = new CountDownLatch(3);
...
latch.await(); // Wait for countdown
其他线程然后在完成任务时每次调用latch.countDown()
。倒计时完成后,本例中有三个,执行将继续。
答案 2 :(得分:13)
SwingWorker有doInBackground()
可用于执行任务。您可以选择调用get()
并等待下载完成,或者您可以覆盖done()
方法,该方法将在SwingWorker完成后在事件调度线程上调用。
Swingworker对您当前的方法有优势,因为它具有您正在寻找的许多功能,因此无需重新发明轮子。您可以使用getProgress()
和setProgress()
方法替代runnable上的观察者以获取下载进度。如上所述的done()
方法在工作人员完成执行后调用并在EDT上执行,这允许您在下载完成后加载数据。
答案 3 :(得分:6)
Not方法的更好替代方案已经在一段时间内得到了发展。
join()是另一种选择。
执行给定的任务,在完成所有任务后返回持有其状态和结果的Futures列表。对于返回列表的每个元素,Future.isDone()都为true。
请注意,已完成的任务可能已正常终止或通过抛出异常终止。如果在此操作正在进行时修改了给定集合,则此方法的结果未定义。
ExecutorService.html#invokeAll或ForkJoinPool提供了实现相同目的的其他替代方案。
示例代码段:
.m
答案 4 :(得分:4)
我想你是在后台线程中调用你的下载,例如SwingWorker提供的。如果是这样,那么只需在同一个SwingWorker的doInBackground方法中按顺序调用下一个代码。
答案 5 :(得分:3)
通常,当您想要等待线程完成时,您应该在其上调用join()。
答案 6 :(得分:3)
您可以使用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
答案 7 :(得分:1)
有什么建议/例子吗?我跟着
SwingWorker
...代码非常混乱,我不喜欢这种方法。
而不是等待完成的get()
,而是使用process()
和setProgress()
来显示中间结果,如此简单example或此相关{{3}中所示}。
答案 8 :(得分:0)
join()方法允许一个线程等待另一个线程的完成。但是,与sleep一样,join依赖于操作系统进行计时,所以你不应该假设连接将等待你的时间。指定。