繁体   English   中英

如何在使用 run() 启动线程的 Java 中等待线程完成

[英]How to wait for threads to complete in Java where threads are initiated using run()

我开始这些线程:

          ThreadingHDFSUsage HDFSUsage=new ThreadingHDFSUsage(dcaps);  
          ThreadingRAMandContainers RAMandContainers=new ThreadingRAMandContainers(dcaps);  
          ThreadingCoreNodesHDFSUsage CoreNodesHDFSUsage=new ThreadingCoreNodesHDFSUsage(dcaps);
          ThreadingApplicationMonitoring ApplicationMonitoring= new ThreadingApplicationMonitoring(dcaps);

在执行其他操作之前,我应该如何等待所有这些线程完成。

我的一个线程操作的示例线程类代码是:

public class ThreadingHDFSUsage extends Thread {

//private PhantomJSDriver driver;

private DesiredCapabilities dcaps;

 public ThreadingHDFSUsage(DesiredCapabilities dcaps) {
    // TODO Auto-generated constructor stub
     this.dcaps = dcaps;
}

public void run(){  
     System.out.println("task HDFS Usage");  

    PhantomJSDriver driver = new PhantomJSDriver(dcaps);
    try {
        Thread.sleep(10000);
    } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
     System.out.println(".........HDFS Usage..........");
     String OverallHDFSUsage[] = null;
    try {
        OverallHDFSUsage = HDFSUsage.getWebData(driver,"http://1.2.3.4:8888/dfshealth.html#tab-overview","//*[@id=\"tab-overview\"]/table[2]/tbody/tr[2]/td","");
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
     String OverallHDFSUsage1 = OverallHDFSUsage[0];


 }  
}

同样,我有其他线程的相关代码。

那么,我如何等待所有这 4 个线程操作完成?

只需再次加入()他们:

HDFSUsage.join();  
RAMandContainers.join();
CoreNodesHDFSUsage.join();
ApplicationMonitoring.join();

每个 join() 都等待特定线程完成。

JDK concurrent CompletionService中还有CompletionService 要使用它,您需要从显式Threads切换到任务,表示为Callable<ResultType>Runnable实例。 虽然代码可能看起来稍微复杂一些,但一旦你习惯了它就非常方便:

import java.util.concurrent.*;

class Test {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        CompletionService<String> completionService = new ExecutorCompletionService<>(Executors.newCachedThreadPool());
        completionService.submit(() -> {
            Thread.sleep(5000);
            return "sleeped for 5000 millis";
        });
        completionService.submit(() -> {
            Thread.sleep(1000);
            return "sleeped for 1000 millis";
        });
        // etc
        System.out.println("Completed: " + completionService.take().get());
        System.out.println("Completed: " + completionService.take().get());
    }

}

其他两个答案都是正确的,但为了完整起见,还有另一种方法可以使用Semaphore做您想做的事情。 此方法不会产生与任何其他答案不同的结果,但如果您的任何线程在获得所需结果之后返回之前必须执行一些昂贵的操作,则可能会更快。 在您的每个线程中,一旦所有相关工作完成,就调用s.release() 您的控制器线程可能如下所示...

Semaphore s = new Semaphore(0);
//start all four of your threads here and pass 's' to each
s.acquire(4);

...您的工作线程可能如下所示:

@Override
public void run(){
    //compute results
    s.release(1);
    //do expensive cleanup and return
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM