Java多线程处理,怎么才能知道多线程执行完毕?

作者站长头像
站长
· 阅读数 10

第三方系统提供的接口不支持批量接收数据, 只能一笔一笔的调用,我们有1000多条数据,就得请求1000次这个接口, 效率很是低下! 所以我想利用多线程的方式快速的调用完这1000次接口请求并处理响应(前端调用我这个接口 我立马返回结果了,因为是多线程异步处理,执行完后 前端再查一下结果!) 还有个要求就是 这1000笔执行完成后 调用一个发送短信接口! 然而我通过future.get()来搞(每次接口调用成功返回我都add到List中,最终判断List的size是否是我那1000笔一致,如果一致那么就说明线程执行完毕),结果阻塞了主线程,变成同步了,前端一直得不到响应, 有没有啥好的办法,既让他不阻塞主线程又能知道线程执行完毕!?

回复
1个回答
avatar
test
2024-06-29

用CountDownLatch:

int requestCount = 1000;
CountDownLatch latch = new CountDownLatch(requestCount);

for (int i = 0; i < requestCount; i++) {
    new Thread(() -> {
        // 调用第三方接口
        // ...

        // 操作完成,递减计数器
        latch.countDown();
    }).start();
}

// 新开一个线程等待所有请求完成后发送短信
new Thread(() -> {
    try {
        latch.await();
        // 所有请求完成,发送短信
        // ...
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}).start();

或者用CompletableFuture.allOf。

CompletableFuture[] futures = new CompletableFuture[requestCount];

for (int i = 0; i < requestCount; i++) {
    futures[i] = CompletableFuture.runAsync(() -> {
        // 调用第三方接口
        // ...
    });
}

// 所有请求完成后发送短信
CompletableFuture.allOf(futures).thenRun(() -> {
    // 发送短信
    // ...
});

你理解的没问题用CompletableFuture.runAsync(Runnable runnable, Executor executor)这个方法。这样可以用你自己的线程池来执行这些异步任务:

ExecutorService executor = Executors.newFixedThreadPool(100); 
CompletableFuture[] futures = new CompletableFuture[requestCount];

for (int i = 0; i < requestCount; i++) {
    futures[i] = CompletableFuture.runAsync(() -> {
        // 调用第三方接口
        // ...
    }, executor); // 用自定义线程池
}

// 所有请求完成后发送短信
CompletableFuture.allOf(futures).thenRun(() -> {
    // 发送短信
    // ...
}).thenRun(() -> executor.shutdown()); // 所有任务完成后关闭线程池

Java CompletableFuture 的官方文档

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容