在浏览ListenableFutre界面时,会在文档中注明
addListener()
注册要在给定执行程序上运行的侦听器。听众 将在
Future
的计算完成时运行,或者如果是。{ 计算已经完成,立即。
由于Future.get()
是一个阻塞调用,Java如何保证某些未来是完成的?他们在旋转吗?我理解使用像dagger生成器这样的框架,它有点容易理解(一旦完成任务,写入某些东西,监控线程将被通知)。在ListenableFuture案例中,jvm是否支持这样的开箱即用?
使用wait()/notify()
类似机制?
FollowUp Question :就像你们所有人所说的那样,调用者实际上保证了监听器的运行,正常情况下使用ListenableFuture
将ListenableFuture future = Caller.call()
,调用者和被调用者在不同的线程中,甚至在不同的JVM中,如何在java中完成?监听器存储在调用者线程和被调用者线程中?或者在不同的JVM中使用远程reigstery?
答案 0 :(得分:2)
ListenableFuture
没有什么神奇之处 - 接口的契约只要求任何实现在完成时调用任何已注册的侦听器(或者如果已经完成则立即调用)。
查看一个这样的实现AbstractFuture
可能会有所帮助 - 具体看一下.complete()
method,它将在未来变为"完成后立即调用" (通过完成,失败或被取消)。为了兼顾快速和线程安全,细节有点复杂,但基本上就是这样。
答案 1 :(得分:1)
如前所述,了解ListenableFuture
的最佳方法是查看它是如何实现的。当您调用addListener(Runnable listener, Executor exec)
时,您提供了一个Runnable
侦听器和一个Executor
来运行此侦听器,因此您决定如何执行侦听器。
监听器存储在调用者线程和被调用者线程中?
侦听器存储在未来的ExecutionList
:
// The execution list to hold our executors.
private final ExecutionList executionList = new ExecutionList();
addListener(Runnable listener, Executor exec)
就是这样:
public void addListener(Runnable listener, Executor exec) {
executionList.add(listener, exec);
}
因此,当未来完成时,它会调用set(V value)
方法:
protected boolean set(@Nullable V value) {
boolean result = sync.set(value);
if (result) {
executionList.execute();
}
return result;
}
并且所有侦听器都执行如下:executor.execute(runnable);
答案 2 :(得分:0)
我想补充答案。
番石榴并不保证。 如果您关闭JVM或JVM崩溃,则不会调用任何侦听器。 如果在不取消期货的情况下关闭执行程序,则也不会调用任何侦听器。我的意思是这个案子:
ExecutorService executorService = Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(false);
return t;
}
});
ListenableFuture<?> listenableFuture = JdkFutureAdapters.listenInPoolThread(
executorService.submit(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("run!!!");
}
}),
executorService
);
Futures.addCallback(listenableFuture, new FutureCallback<Object>() {
@Override
public void onSuccess(@Nullable Object result) {
System.out.println("onSuccess");
}
@Override
public void onFailure(Throwable t) {
System.out.println("onFailure");
}
});
MoreExecutors.shutdownAndAwaitTermination(executorService, 3, TimeUnit.SECONDS);
我没有看到“onSuccess”或“onFailure”,是吗?
在JVM运行的常规工作流程中,Guava使用CAS只调用一次侦听器,您也可以在源代码中看到它。