St.*_*rio 6 java multithreading future
从文档中
Future表示异步计算的结果.
是否意味着调用Future#get方法的线程不应该是执行计算的线程?那么,如果调用Future#的线程如果还没有开始计算,它是否合适?我不确定我是否可以将其称为异步计算...
术语“异步计算”并不强制要求计算必须在不同的线程中运行。如果 API 设计者打算这样做,他们就会编写“在不同线程中运行的计算”。在这里,它只是意味着没有关于计算何时发生的规范。
同样,JRE 提供的现有实现不会在不同线程中强制执行计算。可能是最著名的实现,FutureTask可以如下使用:
Callable<String> action = new Callable<String>() {
public String call() {
return "hello "+Thread.currentThread();
}
};
FutureTask<String> ft=new FutureTask<>(action);
ft.run();
System.out.println(ft.get());
Run Code Online (Sandbox Code Playgroud)
通常, 的实例FutureTask是由一个ExecutorService决定的,它将决定何时以及由哪个线程执行计算:
ExecutorService runInPlace=new AbstractExecutorService() {
public void execute(Runnable command) {
command.run();
}
public void shutdown() {}
public List<Runnable> shutdownNow() { return Collections.emptyList(); }
public boolean isShutdown() { return false; }
public boolean isTerminated() { return false; }
public boolean awaitTermination(long timeout, TimeUnit unit) { return false; }
};
Future<String> f=runInPlace.submit(action);
System.out.println(ft.get());
Run Code Online (Sandbox Code Playgroud)
请注意,此execute()实现不违反其合同:
在将来的某个时间执行给定的命令。根据 Executor 实现的判断,该命令可以在新线程、池线程或调用线程中执行。
注意“或在调用线程中”...
另一个实现是ForkJoinTask:
ForkJoinTask<String> fjt=new RecursiveTask<String>() {
protected String compute() {
return "hello "+Thread.currentThread();
}
};
fjt.invoke();
System.out.println(fjt.get());
Run Code Online (Sandbox Code Playgroud)
请注意,虽然此类任务旨在支持拆分为可由不同线程执行的子任务,但此处有意使用调用线程。如果任务无法拆分,它会完全在调用者的线程中运行,因为这是最有效的解决方案。
这些示例都在调用者线程中运行,但它们都不会执行get()方法内的任务。原则上,这不会违反合同,因为它返回结果值,当计算已经执行时,但是,在尝试get(long timeout, TimeUnit unit)正确实现时可能会遇到问题。相比之下,非工作cancel()仍然在合同范围内。