use*_*663 3 java concurrency java-8 completable-future
我有两个问题:1.Callable在Java 8中运行作为任务的最简单的规范形式是什么,捕获和处理结果?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
}
}
Run Code Online (Sandbox Code Playgroud)
有没有更简单,更清晰的Java-8方法呢?我如何消除System.in.read()支持更好的方法?
等待多个CompletableFuture实例完成的规范方法是根据所有实例创建一个新实例CompletableFuture.allOf.您可以使用这个新的未来等待其完成或安排新的后续行动,就像其他任何一样CompletableFuture:
CompletableFuture.allOf(
IntStream.range(0,10).mapToObj(SimpleTask::new)
.map(s -> CompletableFuture.supplyAsync(s).thenAccept(System.out::println))
.toArray(CompletableFuture<?>[]::new)
).join();
Run Code Online (Sandbox Code Playgroud)
当然,如果您放弃为每个任务分配唯一ID,它总是变得更简单.由于您的第一个问题是有关Callable,我将演示如何轻松提交多个类似的任务,Callable通过S ExecutorService:
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();
Run Code Online (Sandbox Code Playgroud)
返回的执行程序服务Executors.newCachedThreadPool()是非共享的,即使您忘记调用也不会保持活动状态shutDown(),但在所有线程终止之前最多可能需要一分钟.
因为你的第一个问题字面上是:" 在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);
Run Code Online (Sandbox Code Playgroud)
没有简单的方法......
| 归档时间: |
|
| 查看次数: |
105 次 |
| 最近记录: |