4

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

 4 weeks ago
source link: https://blog.51cto.com/mecode/10518912
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

【架构之路】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提供了一种简洁且高效的解决方案。

  • 收藏
  • 评论
  • 分享
  • 举报

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK