Java多线程之invokeAll

引言

在日常的Java开发中,我们经常会遇到需要并发执行多个任务的场景。Java提供了多线程的机制来实现并发执行,其中一个常用的方法是invokeAll。本文将详细介绍invokeAll的使用方法,并通过代码示例和图示进行说明。

什么是invokeAll

invokeAll是Java多线程中的一个方法,它允许我们并发地执行一组任务,并等待所有任务完成。它接收一个Callable类型的任务列表,并返回一个List<Future>类型的结果列表。每个Callable任务表示一个需要执行的任务,而Future表示任务的结果。

invokeAll的使用方法

1. 创建Callable任务列表

首先,我们需要创建一个Callable类型的任务列表,其中每个任务表示一个需要执行的任务。Callable是一个包含返回结果的任务,它定义了一个call方法,在该方法中编写实际的执行逻辑。

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

public class MyTask implements Callable<Integer> {
    private int taskId;

    public MyTask(int taskId) {
        this.taskId = taskId;
    }

    @Override
    public Integer call() throws Exception {
        // 执行任务逻辑
        return taskId * 2;
    }
}

public class Main {
    public static void main(String[] args) {
        // 创建任务列表
        List<Callable<Integer>> tasks = new ArrayList<>();
        for (int i = 1; i <= 3; i++) {
            tasks.add(new MyTask(i));
        }
    }
}

在上面的代码中,我们创建了一个MyTask类,它实现了Callable<Integer>接口。在call方法中,我们简单地将任务ID乘以2作为返回结果。

2. 调用invokeAll方法

接下来,我们需要调用invokeAll方法来执行任务,并等待所有任务完成。invokeAll方法接收一个Callable任务列表,并返回一个List<Future>类型的结果列表。

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 Main {
    public static void main(String[] args) {
        // 创建任务列表
        List<Callable<Integer>> tasks = new ArrayList<>();
        for (int i = 1; i <= 3; i++) {
            tasks.add(new MyTask(i));
        }

        // 创建线程池
        ExecutorService executor = Executors.newFixedThreadPool(3);

        try {
            // 执行任务并等待所有任务完成
            List<Future<Integer>> results = executor.invokeAll(tasks);

            // 处理任务结果
            for (Future<Integer> result : results) {
                try {
                    Integer taskResult = result.get();
                    System.out.println("Task result: " + taskResult);
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 关闭线程池
            executor.shutdown();
        }
    }
}

在上面的代码中,我们创建了一个固定大小的线程池,并使用invokeAll方法执行任务。invokeAll方法将并发地执行所有任务,并等待所有任务完成。

3. 处理任务结果

invokeAll方法执行完毕后,我们可以通过Future对象获取每个任务的结果。Future对象表示一个任务的结果,它提供了get方法来获取任务的返回结果。我们可以使用一个循环来遍历结果列表,并处理每个任务的结果。

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 Main {
    public static void main(String[] args) {
        // 创建任务列表
        List<Callable<Integer>> tasks = new ArrayList<>();
        for (int i = 1; i <= 3; i++) {
            tasks.add(new MyTask(i));
        }

        // 创建线程池
        ExecutorService executor = Executors.newFixedThreadPool(3);

        try {
            // 执行任务并等待所有任务完成
            List<Future<Integer>> results = executor.invokeAll(tasks);

            // 处理任务结果
            for (Future<Integer> result : results) {
                try {
                    Integer taskResult = result.get();
                    System.out