gpt4 book ai didi

Java 8 并发最简单的基本任务规范形式

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:53:58 24 4
gpt4 key购买 nike

我有两个问题:1. 在 Java 8 中将 Callable 作为任务运行、捕获和处理结果的最简单规范形式是什么?2. 在下面的示例中,在所有任务完成之前保持主进程打开的最佳/最简单/最清晰的方法是什么?

这是我目前的示例——这是 Java 8 中最好的方法还是有更基本的方法?

import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;

public class SimpleTask implements Supplier<String> {
private SplittableRandom rand = new SplittableRandom();
final int id;
SimpleTask(int id) { this.id = id; }
@Override
public String get() {
try {
TimeUnit.MILLISECONDS.sleep(rand.nextInt(50, 300));
} catch(InterruptedException e) {
System.err.println("Interrupted");
}
return "Completed " + id + " on " +
Thread.currentThread().getName();
}
public static void main(String[] args) throws Exception {
for(int i = 0; i < 10; i++)
CompletableFuture.supplyAsync(new SimpleTask(i))
.thenAccept(System.out::println);
System.in.read(); // Or else program ends too soon
}
}

是否有更简单、更清晰的 Java-8 方法来做到这一点?我如何消除 System.in.read() 以支持更好的方法?

最佳答案

等待多个CompletableFuture 实例完成的规范方法是通过CompletableFuture.allOf 创建一个依赖于所有实例的新实例。 .您可以使用这个新的 Future 来等待其完成或安排新的后续操作,就像任何其他 CompletableFuture 一样:

CompletableFuture.allOf(
IntStream.range(0,10).mapToObj(SimpleTask::new)
.map(s -> CompletableFuture.supplyAsync(s).thenAccept(System.out::println))
.toArray(CompletableFuture<?>[]::new)
).join();

当然,如果您放弃为每个任务分配一个唯一的 ID,它总是会变得更简单。由于您的第一个问题是关于 Callable 的,我将演示如何通过 ExecutorService 轻松提交多个与 Callable 类似的任务:

ExecutorService pool = Executors.newCachedThreadPool();
pool.invokeAll(Collections.nCopies(10, () -> {
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(
ThreadLocalRandom.current().nextInt(50, 300)));
final String s = "Completed on "+Thread.currentThread().getName();
System.out.println(s);
return s;
}));
pool.shutdown();

Executors.newCachedThreadPool() 返回的执行器服务是未共享的,即使您忘记调用 shutDown() 也不会保持 Activity 状态,但它可能需要在所有线程终止之前最多一分钟。

由于您的第一个问题确实是:“在 Java 8 中将 Callable 作为任务运行、捕获和处理结果的最简单的规范形式是什么?”,答案可能是最简单的表单仍然直接调用它的 call() 方法,例如

Callable<String> c = () -> {
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(
ThreadLocalRandom.current().nextInt(50, 300)));
return "Completed on "+Thread.currentThread().getName();
};
String result = c.call();
System.out.println(result);

没有比这更简单的方法了……

关于Java 8 并发最简单的基本任务规范形式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36069836/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com