如果你需要使用Callable接口来替代Runnable接口来执行任务,可以使用ExecutorService.submit(Callable)方法来提交任务,该方法会返回一个Future对象,该对象可以用来获取任务的返回值。
以下是一个示例代码,展示了如何使用CountDownLatch和Future来实现等待所有线程执行完毕并获取返回值的功能:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class WaitThreadExample {
public static void main(String[] args) {
int nThreads = 5;
CountDownLatch latch = new CountDownLatch(nThreads);
ExecutorService executor = Executors.newFixedThreadPool(nThreads);
List<Future<Integer>> futures = new ArrayList<>();
for (int i = 0; i < nThreads; i++) {
futures.add(executor.submit(new Callable<Integer>() {
public Integer call() throws Exception {
// 线程执行任务
System.out.println("Thread " + Thread.currentThread().getName() + " is running");
// 计数器减1
latch.countDown();
return 1; // 返回值
}
}));
}
// 等待所有线程执行完毕
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出结果
int sum = 0;
for (Future<Integer> future : futures) {
try {
sum += future.get(); // 获取返回值并累加
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
System.out.println("All threads have finished executing");
System.out.println("Sum of return values: " + sum);
// 关闭线程池
executor.shutdown();
}
}
上述代码与之前的示例代码类似,但是使用了Callable接口来执行任务,提交任务的方法也由executor.submit(Runnable)变为了executor.submit(Callable),同时List<Future> futures用来存储每个任务的Future对象,以便在所有任务执行完毕后获取它们的返回值。在每个Callable任务的call()方法中,除了执行任务之外,还使用latch.countDown()方法将计数器的值减1,并返回一个整数值1作为该任务的返回值。
在等待所有线程执行完毕之后,可以使用Future.get()方法获取每个任务的返回值,并将它们累加到sum变量中。最后输出计数器的值以及所有任务的返回值之和,并关闭线程池。
执行上述代码的结果应该是类似于以下的输出:
Thread pool-1-thread-2 is running
Thread pool-1-thread-1 is running
Thread pool-1-thread-3 is running
Thread pool-1-thread-4 is running
Thread pool-1-thread-5 is running
All threads have finished executing
Sum of return values: 5