fre*_*low 6 java concurrency multithreading scala java.util.concurrent
我写了一个基于随机性生成迷宫的函数.大多数时候,这个功能非常快.但每隔一段时间,由于随机数运气不好,需要几秒钟.
我想多次并行启动这个功能,让最快的功能"赢".
Scala标准库(或Java标准库)是否为此作业提供了合适的工具?
你可以使用Future:
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
val futures = for (_ <- 1 to 4) yield Future { /* computation */ }
val resultFuture = Future.firstCompletedOf(futures)
Run Code Online (Sandbox Code Playgroud)
如果你想阻止(我认为你这样做),你可以使用Await.result:
import scala.concurrent.Await
import scala.concurrent.duration.Duration
val result = Await.result(resultFuture, Duration.Inf)
Run Code Online (Sandbox Code Playgroud)
7年后,我偶然发现了它ExecutorService.invokeAny,它正是我想要的:
执行给定的任务,返回已成功完成的任务的结果(即,不引发异常)(如果有的话)(在给定的超时时间过去之前)。
正常或异常返回时,未完成的任务将被取消。
<T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException;
<T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
Run Code Online (Sandbox Code Playgroud)
实现草图:
class LabyrinthGenerator implements Callable<Labyrinth> {
private static final int N = 16;
private static final ExecutorService pool = Executors.newFixedThreadPool(N);
public static Labyrinth generate() {
while (true) {
List<LabyrinthGenerator> generators = Stream.generate(LabyrinthGenerator::new)
.limit(N)
.collect(Collectors.toList());
try {
return pool.invokeAny(generators, 1, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException ex) {
// all attempts failed or timed out, try again
}
}
}
@Override
public Labyrinth call() throws Exception {
// ...
if (Thread.currentThread().isInterrupted()) {
// some other generator found a result, abort
}
// ...
}
}
Run Code Online (Sandbox Code Playgroud)