The*_*ode 54 java multithreading asynchronous executorservice executor
在将此标记为重复之前,请仔细阅读该问题.
下面是伪代码的片段.我的问题是 - 以下代码是否没有打败并行异步处理的概念?
我问这个的原因是因为在下面的代码中,主线程将提交一个要在不同线程中执行的任务.在队列中提交任务后,它会阻止Future.get()方法为任务返回值.我宁愿在主线程中执行任务,而不是提交到不同的线程并等待结果.通过在新线程中执行任务我获得了什么?
我知道你可以等待有限的时间等,但如果我真的关心结果呢?如果要执行多个任务,问题会变得更糟.在我看来,我们只是同步地完成工作.我知道Guava库提供了非阻塞侦听器接口.但我很想知道我对Future.get()API的理解是否正确.如果它是正确的,为什么Future.get()设计为阻止从而打败整个并行处理过程?
注 - 为了记录,我使用JAVA 6
public static void main(String[] args){
private ExectorService executorService = ...
Future future = executorService.submit(new Callable(){
public Object call() throws Exception {
System.out.println("Asynchronous Callable");
return "Callable Result";
}
});
System.out.println("future.get() = " + future.get());
}
Run Code Online (Sandbox Code Playgroud)
Joh*_*ohn 45
Future为你提供isDone()没有阻塞的方法,如果计算完成则返回true,否则返回false.
Future.get() 用于检索计算结果.
你有几个选择:
isDone(),如果结果准备就绪,请通过调用请求它get(),注意没有阻塞get()get(long timeout, TimeUnit unit)整个过程Future API是从执行并行任务的线程中获取值的简单方法.如果您愿意,可以同步或异步完成此操作,如上面的项目符号所述.
使用CACHE示例进行更新
这是Java Concurrency In Practice中的一个缓存实现,是一个很好的用例Future.
Future其他调用者.这很容易通过FutureAPI 实现.
package net.jcip.examples;
import java.util.concurrent.*;
/**
* Memoizer
* <p/>
* Final implementation of Memoizer
*
* @author Brian Goetz and Tim Peierls
*/
public class Memoizer <A, V> implements Computable<A, V> {
private final ConcurrentMap<A, Future<V>> cache
= new ConcurrentHashMap<A, Future<V>>();
private final Computable<A, V> c;
public Memoizer(Computable<A, V> c) {
this.c = c;
}
public V compute(final A arg) throws InterruptedException {
while (true) {
Future<V> f = cache.get(arg);
// computation not started
if (f == null) {
Callable<V> eval = new Callable<V>() {
public V call() throws InterruptedException {
return c.compute(arg);
}
};
FutureTask<V> ft = new FutureTask<V>(eval);
f = cache.putIfAbsent(arg, ft);
// start computation if it's not started in the meantime
if (f == null) {
f = ft;
ft.run();
}
}
// get result if ready, otherwise block and wait
try {
return f.get();
} catch (CancellationException e) {
cache.remove(arg, f);
} catch (ExecutionException e) {
throw LaunderThrowable.launderThrowable(e.getCause());
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
下面是伪代码的片段.我的问题是 - 以下代码是否没有打败并行异步处理的概念?
这一切都取决于您的用例:
get()get()超时如果您可以继续而不立即分析结果并在将来检查结果,请使用CompletableFuture(java 8)
可以显式完成的Future(设置其值和状态),并且可以用作CompletionStage,支持在完成时触发的依赖函数和操作.
您可以从Runnable/Callable实现回调机制.看看下面的SE问题:
我想在这个问题上分享更多的理论观点,因为已经有一些技术答案。我想根据评论来回答:
让我给你举个例子。我提交给服务的任务最终会引发 HTTP 请求,HTTP 请求的结果可能需要很多时间。但我确实需要每个 HTTP 请求的结果。任务在循环中提交。如果我等待每个任务返回(get),那么我在这里失去了并行性,不是吗?
这与问题中所说的一致。
假设你有三个孩子,你想为你的生日做一个蛋糕。由于您想制作最美味的蛋糕,因此您需要准备很多不同的东西。所以你要做的就是把配料分成三个不同的清单,因为你住的地方只有 3 家超市出售不同的产品,并为你的每个孩子分配一个任务,simultaneously。
现在,在您开始准备蛋糕之前(让我们再次假设,您需要事先准备好所有食材),您将不得不等待走最长路线的孩子。现在,您需要在开始制作蛋糕之前等待所有成分,这一事实是您的必需品,而不是任务之间的依赖关系。您的孩子一直在尽可能长时间地同时完成任务(例如:直到第一个孩子完成任务)。所以,总而言之,这里有平行度。
当您有 1 个孩子并且您将所有三项任务分配给他/她时,将描述顺序示例。
| 归档时间: |
|
| 查看次数: |
43511 次 |
| 最近记录: |