invokeAll(tasks,time,unit)源码解析

本文详细解析了ForkJoinPool中invokeAll方法的源码,包括接口定义、主要实现类及其工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ExecutorService的invokeAll带参数的方法源码

接口定义

// 需要传递一个Callable的集合,返回Future的List。
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                  long timeout, TimeUnit unit)
        throws InterruptedException;

最主要的实现类

在这里插入图片描述

源码解析

public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                     long timeout, TimeUnit unit)
    throws InterruptedException {
    if (tasks == null)
        throw new NullPointerException();
    long nanos = unit.toNanos(timeout);  // 将超时时间转为nanos
    ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); // 创建futures集合,大小和tasks一样
    boolean done = false;
    try {
        for (Callable<T> t : tasks)
            futures.add(newTaskFor(t));  // 循环遍历tasks,添加到futures集合中,注意这儿是有序的

        final long deadline = System.nanoTime() + nanos; // 计算超时的时间点
        final int size = futures.size();

   
        for (int i = 0; i < size; i++) {  // 循环开启线程执行,超时就返回
            execute((Runnable)futures.get(i));
            nanos = deadline - System.nanoTime();
            if (nanos <= 0L)
                return futures;
        }

        for (int i = 0; i < size; i++) {  // 到这儿说明还没有超时,遍历futures
            Future<T> f = futures.get(i);
            if (!f.isDone()) {  // 判断当前线程是否完成
                if (nanos <= 0L)
                    return futures;
                try {
                    f.get(nanos, TimeUnit.NANOSECONDS); // 这儿是阻塞的,会一直等着线程执行完才会继续循环
                } catch (CancellationException ignore) {
                } catch (ExecutionException ignore) {
                } catch (TimeoutException toe) {
                    return futures;
                }
                nanos = deadline - System.nanoTime(); // 更改每次的剩余时间
            }
        }
        done = true; // 如果在上面的循环过程中所有的线程都返回了,说明没有线程超时
        return futures;  // 如果在循环过程中超时了,还没有循环到的线程也可能已经执行完了
    } finally {
        if (!done) //如果超时了,中断线程,已经有结果的没有影响
            for (int i = 0, size = futures.size(); i < size; i++)
                futures.get(i).cancel(true);
    }
}

就这么多吧,很容易理解的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值