Java等待线程完成

2021/01/01 00:22 · java ·  · 0评论

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

更多信息:

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

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

我有一个帮助程序类,该类管理下载的URL并进行所有对Download的调用。此调用将调用getObject并进行转换。Gui调用helper.getUser()。helper启动线程运行,我希望它在完成时“知道”,以便它可以返回强制转换的对象。

有什么建议/示例吗?我正处于此设计的起步阶段,因此我愿意对其进行更改。

非常感谢你。

更新:

我按照http://download.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html#get进行操作,并使用模式进行阻塞,直到线程完成。代码非常混乱,我不喜欢这种方法。我将继续尝试寻找一种“干净”的方式来处理下载过程的工作流程。

Thread有一个为您加入的方法,该方法将阻塞直到线程执行完毕。

你可以使用一个CountDownLatchjava.util.concurrent包。当在等待线程中继续执行之前,等待一个或多个线程完成时,它非常有用。

例如,等待三个任务完成:

CountDownLatch latch = new CountDownLatch(3);
...
latch.await(); // Wait for countdown

然后,其他线程latch.countDown()在完成其任务时将每次调用倒计时完成后,在此示例中为3,执行将继续。

SwingWorker具有doInBackground()可用于执行任务的工具。您可以选择调用get()并等待下载完成,或者可以重写done()一旦SwingWorker完成后将在事件分发线程上调用方法。

Swingworker与您当前的方法相比有很多优势,因为它具有许多您正在寻找的功能,因此无需重新发明轮子。您可以使用getProgress()setProgress()方法来代替可运行对象上的观察器以获取下载进度。done()我上述方法执行的工人完成之后被调用,并在美国东部时间进行,这使得在下载完成后您加载数据。

一段时间以来,已经开发出更好的join()方法替代方法。

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

执行给定的任务,并在所有任务完成时返回保存其状态和结果的期货列表。Future.isDone()对于返回列表的每个元素为true。

请注意,已完成的任务可能已正常终止或引发了异常。如果在进行此操作时修改了给定的集合,则此方法的结果不确定。

ForkJoinPoolExecutors.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;
        }
    }
}

您可以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

我想您是在诸如SwingWorker提供的后台线程中调用下载的。如果是这样,只需在相同的SwingWorker的doInBackground方法中顺序调用下一个代码即可。

通常,当您要等待线程完成时,应在其上调用join()

有什么建议/示例吗?我遵循了SwingWorker...代码非常混乱,我不喜欢这种方法。

如此简单示例或相关示例所示get(),请使用process()setProgress()显示中间结果,而不是等待完成

加入()方法允许一个线程等待another.However完成,如睡眠,参加是依赖于操作系统的时间,所以你不应该假设加入将等待确切只要你指定。

本文地址:http://java.askforanswer.com/javadengdaixianchengwancheng.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!