(目录)
在Java中确保主线程在五个子线程全部执行完成后退出,您可以使用ExecutorService提供的invokeAll()方法或CountDownLatch类来同步线程执行。这里分别给出两种实现方式:
方法一:使用ExecutorService.invokeAll() Java import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future;
public class MainThreadExitAfterSubthreadsComplete {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
List<Callable<Void>> tasks = new ArrayList<>();
for (int i = 0; i < 5; i++) {
final int taskId = i;
tasks.add(() -> {
System.out.println("Task " + taskId + " started");
// Replace with actual task logic
simulateTaskExecution();
System.out.println("Task " + taskId + " finished");
return null;
});
}
try {
executor.invokeAll(tasks);
System.out.println("All subthreads have completed.");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Main thread interrupted.");
}
executor.shutdown(); // Optionally, wait for graceful shutdown here
System.out.println("Main thread exiting.");
}
private static void simulateTaskExecution() {
try {
Thread.sleep(1000); // Simulate task execution time
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
} 在这个示例中,我们创建了一个包含五个Callable任务的列表,并使用executor.invokeAll(tasks)一次性提交所有任务。invokeAll()方法会阻塞直到所有任务都完成。当所有子线程执行完毕后,主线程将继续执行后续代码并最终退出。
方法二:使用CountDownLatch Java import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;
public class MainThreadExitAfterSubthreadsComplete {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
CountDownLatch latch = new CountDownLatch(5);
for (int i = 0; i < 5; i++) {
final int taskId = i;
executor.execute(() -> {
System.out.println("Task " + taskId + " started");
// Replace with actual task logic
simulateTaskExecution();
System.out.println("Task " + taskId + " finished");
latch.countDown(); // Signal completion of this task
});
}
try {
latch.await(); // Block until all tasks complete
System.out.println("All subthreads have completed.");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Main thread interrupted.");
}
executor.shutdown(); // Optionally, wait for graceful shutdown here
System.out.println("Main thread exiting.");
}
private static void simulateTaskExecution() {
try {
Thread.sleep(1000); // Simulate task execution time
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
} 在这个示例中,我们使用CountDownLatch初始化为5(与子线程数量相同)。每个子线程在执行完毕后调用latch.countDown(),表示它已完成。主线程则调用latch.await(),该方法会阻塞直到计数器减至0,即所有子线程都已调用过countDown()。当所有子线程完成时,主线程继续执行后续代码并退出。
两种方法都可以确保主线程在五个子线程全部执行完成后退出。需要获取子任务的执行结果或处理可能抛出的异常,invokeAll()方法(配合Callable和Future)可能更为合适;如果仅需同步子线程的完成状态,CountDownLatch提供了一种简洁且高效的解决方案。