Java 等待ExecutorService.execute中的所有任务完成

Java 等待ExecutorService.execute中的所有任务完成,java,multithreading,parallel-processing,executorservice,Java,Multithreading,Parallel Processing,Executorservice,如何使用 ExecutorService.execute()。有一个函数名为等待终止 但必须在其中提供超时。这并不能保证当 返回本应已完成的所有任务。有没有办法做到这一点?执行方法不会返回任何内容。您可以使用submit方法,该方法返回类型为Future的结果 Future<String> future = executorService.submit(callableTask/runnableTask); 未来= executorService.submit(callabl

如何使用
ExecutorService.execute()。有一个函数名为等待终止
但必须在其中提供超时。这并不能保证当
返回本应已完成的所有任务。有没有办法做到这一点?

执行方法不会返回任何内容。您可以使用submit方法,该方法返回类型为Future的结果

Future<String> future = 
  executorService.submit(callableTask/runnableTask);
未来=
executorService.submit(callableTask/runnableTask);

如果您使用类或它的任何子类,您在其中有一个方法,该方法返回正在积极执行任务的线程数。因此,您可以轮询该方法,直到它变为0,这意味着所有任务都已完成,当前没有新任务正在执行。但是,如果某个任务被卡住了怎么办?我认为您还必须给出一些超时,以防止在这种情况下出现无限循环 这种想法的最大优点是不需要调用shutdown方法

如果您阅读的javadoc(或查看方法签名),您将看到它返回一个
布尔值。此布尔值指示执行器是否终止。您可以使用该信息创建
while
循环,以确定它是否已终止

执行器服务执行器=。。。 executor.shutdown();//关闭执行器,不接受新任务 而(!executor.awaitTermination(100,TimeUnit.millises){}

类似的操作将停止执行器并等待它终止,直到所有任务完成。

有几种方法

您可以先调用,然后返回:

如果此执行器终止,则为true;如果超时已过,则为false 终止前

因此:

有一个名为awaitTermination的函数,但必须设置超时 这并不能保证当它返回所有 这些任务应该已经完成了。有没有办法做到这一点

您只需在循环中调用
waiting

使用等待终止

此实现的完整示例如下:

public class WaitForAllToEnd {

    public static void main(String[] args) throws InterruptedException {
        final int total_threads = 4;
        ExecutorService executor = Executors.newFixedThreadPool(total_threads);
        for(int i = 0; i < total_threads; i++){
            executor.execute(parallelWork(100 + i * 100));
        }

        int count = 0;

        // This is the relevant part
        // Chose the delay most appropriate for your use case
        executor.shutdown();
        while (!executor.awaitTermination(100, TimeUnit.MILLISECONDS)) {
            System.out.println("Waiting "+ count);
            count++;
        }
    }

    private static Runnable parallelWork(long sleepMillis) {
        return () -> {
            try {
                Thread.sleep(sleepMillis);
            } catch (InterruptedException e) {
                // Do Something
            }
            System.out.println("I am Thread : " + Thread.currentThread().getId());
        };
    }
}
public class WaitForAllToEnd {

    public static void main(String[] args) throws InterruptedException {
        final int total_threads = 4;
        CountDownLatch countDownLatch = new CountDownLatch(total_threads);
        ExecutorService executor = Executors.newFixedThreadPool(total_threads);
        for(int i = 0; i < total_threads; i++){
            executor.execute(parallelWork(100 + i * 100, countDownLatch));
        }
        countDownLatch.await();
        System.out.println("Exit");
        executor.shutdown();
    }

    private static Runnable parallelWork(long sleepMillis, CountDownLatch countDownLatch) {
        return () -> {
            try {
                Thread.sleep(sleepMillis);
            } catch (InterruptedException e) {
                // Do Something
            }
            System.out.println("I am Thread : " + Thread.currentThread().getId());
            countDownLatch.countDown();
        };
    }
}
使用循环屏障

另一种方法是使用

公共类WaitForAllToEnd{
公共静态void main(字符串[]args)引发InterruptedException、BrokenBarrierException{
最终int总螺纹数=4;
CyclicBarrier屏障=新的CyclicBarrier(总螺纹数+1);
ExecutorService executor=Executors.newFixedThreadPool(线程总数);
对于(int i=0;i<总线程数;i++){
执行者执行(并行工作(100+i*100,屏障));
}
障碍。等待();
System.out.println(“退出”);
executor.shutdown();
}
专用静态可运行并行工作(长休眠、循环载波屏障){
返回()->{
试一试{
线程。睡眠(sleepMillis);
}捕捉(中断异常e){
//做点什么
}
System.out.println(“我是线程:+Thread.currentThread().getId());
试一试{
障碍。等待();
}catch(中断异常|断开异常){
//做点什么
}
};
}
}
还有其他方法,但这些方法需要更改您的初始需求,即:

提交任务时如何等待所有任务完成 使用ExecutorService.execute()

public class WaitForAllToEnd {

    public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
        final int total_threads = 4;
        CyclicBarrier barrier = new CyclicBarrier(total_threads+ 1);
        ExecutorService executor = Executors.newFixedThreadPool(total_threads);
        for(int i = 0; i < total_threads; i++){
            executor.execute(parallelWork(100 + i * 100, barrier));
        }
        barrier.await();
        System.out.println("Exit");
        executor.shutdown();
    }

    private static Runnable parallelWork(long sleepMillis, CyclicBarrier barrier) {
        return () -> {
            try {
                Thread.sleep(sleepMillis);
            } catch (InterruptedException e) {
                // Do Something
            }
            System.out.println("I am Thread : " + Thread.currentThread().getId());
            try {
                barrier.await();
            } catch (InterruptedException | BrokenBarrierException e) {
              // Do something
            }
        };
    }
}