0
点赞
收藏
分享

微信扫一扫

【架构之路】java线程池执行过程

(目录)

在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提供了一种简洁且高效的解决方案。

举报

相关推荐

0 条评论