Java 在ThreadPoolExecuter的所有任务完成后运行代码

Java 在ThreadPoolExecuter的所有任务完成后运行代码,java,multithreading,Java,Multithreading,我有一个方法,在这个方法中,我使用ThreadPoolExecuter创建了一些文件,然后压缩创建的文件 private void createAndZip(){ // Some Code ThreadPoolExecutor executer = (ThreadPoolExecutor) Executors.newFixedThreadPool(5); for(String str : someStringList){ // This piece of

我有一个方法,在这个方法中,我使用ThreadPoolExecuter创建了一些文件,然后压缩创建的文件

private void createAndZip(){
    // Some Code
    ThreadPoolExecutor executer = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
    for(String str : someStringList){
        // This piece of code creates files and drops to certain location.
        executer.execute(new MyRunnable());
    }
    executer.shutdown();
    // Code to Zip the files created above.
}
现在,我创建zip文件的代码甚至在创建所有文件之前就已经运行,因此并非所有文件都是压缩的


请帮忙。我尝试了睡眠,但无法确定创建文件需要多长时间。

您需要调用executor对象,以等待executor完成关闭。

我使用了CountdownClatch来解决此问题。下面是示例代码

private void createAndZip() throws Exception{

    // Some Code
    ThreadPoolExecutor executer = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);

    for(String str : someStringList){
        // This piece of code creates files and drops to certain location.
        executer.execute(new MyRunnable());
    }
    executer.shutdown();

    while (true) {
            boolean result_ = threadPoolExecutor.awaitTermination(TimeUnit.DAYS, 1);

            if(result_)
                break;
        }
    // Code to Zip the files created above.

    //Code here.
}
private void createAndZip() throws Exception{
    CountDownLatch latch = new CountDownLatch(someStringList.size());
    // Some Code
    ThreadPoolExecutor executer = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);

    for(String str : someStringList){
        // This piece of code creates files and drops to certain location.
        executer.execute(new MyRunnable(latch));
    }
    executer.shutdown();


    // Code to Zip the files created above.
    try {
        latch.await();
    } catch (InterruptedException exception) {
        throw new GIException(exception);
    }

    //Code here.
}

public class MyRunnable implements Runnable{
    CountDownLatch latch = null;

    MyRunnable(CountDownLatch latch){
        this.latch = latch;
    }

    @Override
    public void run() {
        try {
            // Some Logic
            latch.countDown();
            } catch (Exception e) {
              e.printStackTrace();
            }
        }
    }

在代码块中,您正在缩小执行器的返回范围。newFixedThreadPool(5)。您可以选择使用它返回的
ExecutorService
。此类已经具有避免重新实现同步代码(如锁存)的功能。例如:

使用期货

private void createAndZip(ExecutorService executor) throws ExecutionException, InterruptedException {
    // Some Code
    List<String> list = new ArrayList<>();
    // For a number of reasons ExecutorService should be constructed outside
    // ExecutorService executer = Executors.newFixedThreadPool(5);
    List<Future<?>> futures = new ArrayList<>();
    for(String str : list){
        // This piece of code creates files and drops to certain location.
        futures.add(executer.submit(new MyRunnable()));
    }
    // async work
    for (Future<?> future : futures) {
        future.get(); // blocks
    }

    // Code to Zip the files created above.
}
private void createAndZip(ExecutorService executor)抛出ExecutionException、InterruptedException{
//一些代码
列表=新的ArrayList();
//出于多种原因,ExecutorService应该在外部构建
//ExecutorService executer=Executors.newFixedThreadPool(5);

List我想你可以在这里使用
Future
对象。不要在executor上调用
execute()
方法,而是使用
submit()
方法。这应该为你提交给executor的每个任务提供一个
Future
对象。一旦你提交了所有任务,只需在你得到的futures列表上循环,然后调用
get()
。这是一个阻塞调用,它将等待相应的任务完成

这里的优点是,您可以检索任务中抛出的任何异常,然后决定是否压缩文件

请参考此代码-

private void createAndZip() throws Exception {
    // Some Code
    ThreadPoolExecutor executer = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
    // collect all futures
    List<Future> futures = new ArrayList<>();
    for(String str : someStringList){
        // This piece of code creates files and drops to certain location.
        futures.add(executer.submit(new MyRunnable()));
    }
    // wait for all tasks to finish
    try {
        for (Future future : futures) {
            future.get();
        }
    } catch (Exception e) {
        e.printStackTrace();
        if (e instanceof ExecutionException) {
            throw e;
        }
    } finally {
        executer.shutdown();
    }
    // Code to Zip the files created above.
}
private void createAndZip()引发异常{
//一些代码
ThreadPoolExecutor executer=(ThreadPoolExecutor)Executors.newFixedThreadPool(5);
//收集所有期货
列表期货=新的ArrayList();
for(字符串str:someStringList){
//这段代码创建文件并放置到特定位置。
futures.add(executer.submit(newmyrunnable());
}
//等待所有任务完成
试一试{
for(未来:未来){
future.get();
}
}捕获(例外e){
e、 printStackTrace();
if(e ExecutionException实例){
投掷e;
}
}最后{
executer.shutdown();
}
//代码来压缩上面创建的文件。
}

while(foo){break;}
毫无意义。它实际上相当于直接运行
foo;
。@ChrisJester Young你现在能检查一下逻辑吗你可以说
while(!foo){
;-)@ChrisJester-Young我不明白我的方法有什么问题新方法?只是更详细而已。(我已经解释了旧方法的错误。)您可以使用五个线程或多个任务的倒计时锁存器,并在主线程中等待,在任务结束时在每个线程中使用倒计时锁存器,这样在倒计时锁存器达到0后,它将继续。不要忘记检查返回值
private void createAndZip() throws Exception {
    // Some Code
    ThreadPoolExecutor executer = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
    // collect all futures
    List<Future> futures = new ArrayList<>();
    for(String str : someStringList){
        // This piece of code creates files and drops to certain location.
        futures.add(executer.submit(new MyRunnable()));
    }
    // wait for all tasks to finish
    try {
        for (Future future : futures) {
            future.get();
        }
    } catch (Exception e) {
        e.printStackTrace();
        if (e instanceof ExecutionException) {
            throw e;
        }
    } finally {
        executer.shutdown();
    }
    // Code to Zip the files created above.
}