You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 25中无法触发StructuredTaskScope.TimeoutException的问题求助

Java 25中无法触发StructuredTaskScope.TimeoutException的问题求助

我最近在Java 25中使用StructuredTaskScope时遇到了一个困惑的问题:明明给任务设置了超时时间,却始终无法触发StructuredTaskScope.TimeoutException,任务反而正常执行完成了。

具体场景是:我提交了一个需要休眠10秒才会返回结果的任务,同时给StructuredTaskScope配置了2秒的超时。按照预期,这个任务应该在2秒后触发超时异常,但实际运行时,任务居然成功执行完毕,控制台还输出了任务返回的"a"。

以下是我的完整代码实现:

package com.tugalsan.tst.thread;

import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.StructuredTaskScope;
import java.util.concurrent.StructuredTaskScope.Joiner;
import java.util.concurrent.StructuredTaskScope.Subtask.State;

public class Main {
    public static void main(String... s) {
        Callable<String> tenSecsTask = () -> {
            Thread.sleep(Duration.ofSeconds(10));
            return "a";
        };

        var allAwait = allAwait("allAwait", Duration.ofSeconds(2), tenSecsTask);
        allAwait.resultsSuccessful().forEach(IO::println);
        IO.println("main.done..");
    }

    public static record AllAwait<R>(
            String name,
            Duration timeout,
            List<R> resultsSuccessful,
            List<StructuredTaskScope.Subtask<R>> resultsFailedOrUnavailable,
            Optional<StructuredTaskScope.TimeoutException> timeoutException
    ) {}

    public static <R> AllAwait<R> allAwait(String name, Duration timeout, Callable<R>... callables) {
        try (var scope = StructuredTaskScope.open(Joiner.<R>awaitAll(), cf -> {
            if (name != null) {
                cf.withName(name);
            }
            if (timeout != null) {
                cf.withTimeout(timeout);
            }
            return cf;
        })) {
            var subTasks = Arrays.stream(callables).map(scope::fork).toList();
            scope.join();

            var resultsSuccessful = subTasks.stream()
                    .filter(st -> st.state() == State.SUCCESS)
                    .map(StructuredTaskScope.Subtask::get)
                    .toList();
            var resultsFailedOrUnavailable = subTasks.stream()
                    .filter(st -> st.state() == State.FAILED || st.state() == State.UNAVAILABLE)
                    .toList();

            return new AllAwait<>(name, timeout, resultsSuccessful, resultsFailedOrUnavailable, Optional.empty());
        } catch (InterruptedException | StructuredTaskScope.TimeoutException e) {
            throwIfInterruptedException(e);
            if (e instanceof StructuredTaskScope.TimeoutException et) {
                return new AllAwait<>(name, timeout, List.of(), List.of(), Optional.of(et));
            }
            return null;
        }
    }

    // 补充的InterruptedException处理代码
    @SuppressWarnings("unchecked")
    private static <T extends Throwable> void _throwAsUncheckedException(Throwable exception) throws T {
        throw (T) exception;
    }

    @Deprecated // only internalUse
    private static void throwAsUncheckedException(Throwable exception) {
        Main.<RuntimeException>_throwAsUncheckedException(exception);
    }

    public static <R> R throwIfInterruptedException(Throwable t) {
        if (isInterruptedException(t)) {
            Thread.currentThread().interrupt();
            throwAsUncheckedException(t);
        }
        return null;
    }

    public static boolean isInterruptedException(Throwable t) {
        if (t instanceof InterruptedException) {
            return true;
        }
        if (t.getCause() != null) {
            return isInterruptedException(t.getCause());
        }
        return false;
    }
}

运行程序后的控制台输出如下:

Executing command line: [C:\bin\java\home\bin\java.exe, --enable-preview, --enable-preview, --add-modules, jdk.incubator.vector, -classpath, C:\git\tst\com.tugalsan.tst.thread\target\classes, com.tugalsan.tst.thread.Main]
WARNING: Using incubator modules: jdk.incubator.vector
a
main.done..

我已经补充了InterruptedException的相关处理逻辑,但问题依然存在。有没有熟悉StructuredTaskScope的朋友能帮我排查一下,到底是代码哪里的问题导致超时没有生效?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 08:44:30