All*_*lan 56 java swing multithreading download wait
我有一个线程下载数据,我想等到下载完成后再加载数据.有这样做的标准方法吗?
更多信息:
我有一个从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和使用模式来阻止,直到线程完成.代码非常混乱,我不喜欢这种方法.我将继续尝试找到一种"干净"的方式来处理下载过程的工作流程.
unh*_*ler 70
Thread
有一种方法可以帮助你.join将阻塞,直到线程执行完毕.
小智 56
你可以使用一个CountDownLatch
从java.util.concurrent
包.在等待一个或多个线程完成之前,它在等待线程中继续执行之前非常有用.
例如,等待完成三个任务:
CountDownLatch latch = new CountDownLatch(3);
...
latch.await(); // Wait for countdown
Run Code Online (Sandbox Code Playgroud)
然后,其他线程latch.countDown()
在完成任务时每次调用.倒计时完成后,本例中有三个,执行将继续.
tst*_*ens 13
SwingWorker类有doInBackground()
你可以用它来执行任务.您可以选择调用get()
并等待下载完成,或者您可以覆盖done()
SwingWorker完成后将在事件调度线程上调用的方法.
Swingworker对您当前的方法有优势,因为它具有您正在寻找的许多功能,因此无需重新发明轮子.您可以使用getProgress()
和setProgress()
方法替代runnable上的观察者以获取下载进度.上述done()
方法在工作人员完成执行并在EDT上执行后调用,这允许您在下载完成后加载数据.
join()方法的更好替代方案已经在一段时间内得到了发展.
ExecutorService.html#invokeAll是一种替代方案.
执行给定的任务,返回完成所有状态和结果的Futures列表.对于返回列表的每个元素,Future.isDone()都为true.
请注意,已完成的任务可能正常终止或通过抛出异常终止.如果在此操作正在进行时修改了给定集合,则此方法的结果是不确定的.
ForkJoinPool或Executors.html#newWorkStealingPool提供了其他替代方案来实现相同的目的.
示例代码段:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
您可以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();
}
Run Code Online (Sandbox Code Playgroud)
在此处查看完整的详细信息:http : //www.letmeknows.com/2017/04/24/wait-for-threads-to-finish-java
我想您是在后台线程(例如 SwingWorker 提供的线程)中调用下载。如果是这样,那么只需在同一个 SwingWorker 的 doInBackground 方法中按顺序调用下一个代码。
归档时间: |
|
查看次数: |
163021 次 |
最近记录: |