Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 8 CompletableFuture、Stream和超时_Java_Concurrency_Java 8_Java Stream_Completable Future - Fatal编程技术网

Java 8 CompletableFuture、Stream和超时

Java 8 CompletableFuture、Stream和超时,java,concurrency,java-8,java-stream,completable-future,Java,Concurrency,Java 8,Java Stream,Completable Future,我正在尝试使用CompletableFuture和Stream 到目前为止,我已经: public static void main(String[] args) throws InterruptedException, ExecutionException { System.out.println("start"); List<String> collect = Stream.of("1", "2", "3", "4", "5", "6",

我正在尝试使用
CompletableFuture
Stream
到目前为止,我已经:

public static void main(String[] args) throws InterruptedException, ExecutionException {
    System.out.println("start");

    List<String> collect = Stream.of("1", "2", "3", "4", "5",
            "6", "7")
            .map(x -> CompletableFuture.supplyAsync(getStringSupplier(x)))
            .collect(Collectors.toList())
            .stream()
            .map(CompletableFuture::join)
            .collect(Collectors.toList());
    System.out.println("stop out!");
}


public static Supplier<String> getStringSupplier(String text) {
    return () -> {

        System.out.println("start " + text);
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("stop " + text);
        return "asd" + text;
    };
}
publicstaticvoidmain(String[]args)抛出InterruptedException、ExecutionException{
系统输出打印项次(“开始”);
List collect=Stream.of(“1”、“2”、“3”、“4”、“5”),
"6", "7")
.map(x->CompletableFuture.SupplySync(getStringSupplier(x)))
.collect(收集器.toList())
.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
System.out.println(“停止!”);
}
公共静态供应商getStringSupplier(字符串文本){
返回()->{
System.out.println(“开始”+文本);
试一试{
时间单位。秒。睡眠(2);
}捕捉(中断异常e){
e、 printStackTrace();
}
System.out.println(“停止”+文本);
返回“asd”+文本;
};
}
输出良好:

开始
开始1
开始4
开始3
开始2
开始5
开始6
开始7
停止4
第一站
停止5
第二站
停止6
第三站
第七站
住手

但是现在我想给这个作业添加超时。假设它应该在1秒后取消。并将null或其他值返回到
collect
列表。(我更喜欢一些表示原因的值)

我怎样才能做到这一点


提前感谢您的帮助。

您可以在另一个可完成的将来包装此作业,如果超过给定的时间,它将发出TimeoutException。如果您想专门处理TimeoutException catch块,可以将其分离

    List<String> collect = null;
    try {
        collect = CompletableFuture.supplyAsync(() ->
                Stream.of("1", "2", "3", "4", "5",
                        "6", "7")
                        .map(x -> CompletableFuture.supplyAsync(getStringSupplier(x)))
                        .collect(Collectors.toList())
                        .stream()
                        .map(CompletableFuture::join)
                        .collect(Collectors.toList())
        ).get(5, TimeUnit.SECONDS);
    } catch (InterruptedException | ExecutionException | TimeoutException e) {
        e.printStackTrace();
        //separate out the TimeoutException if you want to handle it differently 

    }

    System.out.println(collect); //would be null in case of any exception
List collect=null;
试一试{
collect=CompletableFuture.supplySync(()->
“1”、“2”、“3”、“4”、“5”流,
"6", "7")
.map(x->CompletableFuture.SupplySync(getStringSupplier(x)))
.collect(收集器.toList())
.stream()
.map(CompletableFuture::join)
.collect(收集器.toList())
).get(5,时间单位秒);
}捕获(InterruptedException | ExecutionException | TimeoutException e){
e、 printStackTrace();
//如果希望以不同的方式处理,请将TimeoutException分离出来
}
系统输出打印项次(收集)//如果出现任何异常,则为空

您可以尝试CompletableFuture的重载supplyAsync方法,并使用执行器参数(CompletableFuture.supplyAsync(getStringSupplier(x),timeoutExecutorService))并可以引用timeoutExecutorService。

我找到了这样做的方法:

 private static final ScheduledExecutorService scheduler =
        Executors.newScheduledThreadPool(
                1,
                new ThreadFactoryBuilder()
                        .setDaemon(true)
                        .setNameFormat("failAfter-%d")
                        .build());

public static void main(String[] args) throws InterruptedException, ExecutionException {
    System.out.println("start");
    final CompletableFuture<Object> oneSecondTimeout = failAfter(Duration.ofSeconds(1))
            .exceptionally(xxx -> "timeout exception");
    List<Object> collect = Stream.of("1", "2", "3", "4", "5", "6", "7")
            .map(x -> CompletableFuture.anyOf(createTaskSupplier(x)
                    , oneSecondTimeout))
            .collect(Collectors.toList())
            .stream()
            .map(CompletableFuture::join)
            .collect(Collectors.toList());
    System.out.println("stop out!");
    System.out.println(collect);
}

public static CompletableFuture<String> createTaskSupplier(String x) {
    return CompletableFuture.supplyAsync(getStringSupplier(x))
            .exceptionally(xx -> "PROCESSING ERROR : " + xx.getMessage());
}


public static Supplier<String> getStringSupplier(String text) {
    return () -> {

        System.out.println("start " + text);
        try {
            TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (text.equals("1")) {
            throw new RuntimeException("LOGIC ERROR");
        }
        try {
            if (text.equals("7"))
                TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("stop " + text);
        return "result " + text;
    };
}

public static <T> CompletableFuture<T> failAfter(Duration duration) {
    final CompletableFuture<T> promise = new CompletableFuture<>();
    scheduler.schedule(() -> {
        final TimeoutException ex = new TimeoutException("Timeout after " + duration);
        return promise.completeExceptionally(ex);
    }, duration.toMillis(), MILLISECONDS);
    return promise;
}

您对此有何看法,您能发现该解决方案的任何缺陷吗?

对于不受Java 8限制的其他人,您可以使用Java 9中引入的方法

List<String> collect = Stream.of("1", "2", "3", "4", "5", "6", "7")
        .map(x -> CompletableFuture.supplyAsync(getStringSupplier(x))
                .completeOnTimeout(null , 1, SECONDS))
        .filter(Objects::nonNull)
        .collect(toList())
        .stream()
        .map(CompletableFuture::join)
        .collect(toList());
List collect=Stream.of(“1”、“2”、“3”、“4”、“5”、“6”、“7”)
.map(x->CompletableFuture.SupplySync(getStringSupplier(x))
.completeOnTimeout(空,1秒))
.filter(对象::非空)
.collect(toList())
.stream()
.map(CompletableFuture::join)
.collect(toList());

该解决方案的问题是,如果出现异常
collect
列表为
null
,那么我将失去成功执行的数据,我不能让它发生。您是对的,可以工作。但该解决方案在
CompletableFuture
上使用
功能。我更喜欢使用
CompletableFuture
对象,因为我想学习新东西。在Java 9中,使用
CompletableFuture#completeonttimeout
()到目前为止(可能会有一段时间)我的公司使用Java 8,所以我不能使用:)
List<String> collect = Stream.of("1", "2", "3", "4", "5", "6", "7")
        .map(x -> CompletableFuture.supplyAsync(getStringSupplier(x))
                .completeOnTimeout(null , 1, SECONDS))
        .filter(Objects::nonNull)
        .collect(toList())
        .stream()
        .map(CompletableFuture::join)
        .collect(toList());