3
- 的
ExecutorService
别人提供。 - A
Runnable
任务在中断后自行清理。 - 一个
Runnable
听众
我的工作是在其上运行ExecutorService
的任务,然后在同一ExecutorService
任务返回后的某个时间运行监听器,无论是正常(通过return
)或抛出一个异常。我回到我的客户Future
,他(有时)拨打cancel(true)
。
我的第一个想法是使用Guava的ListenableFuture.addListener
...但是这会在取消未来之后立即执行侦听器,而不是在任务返回之后执行。但是,如果在将侦听器添加到将来之前完成任务,那么它具有很好的属性,即侦听器将立即执行。我已将此解决方案包含在下面的SSCCE中。
从下面的例子中,我想如下:
Task Started
Task Canceling
Task Cancelled
**Listener Started**
我其实得到的是:
Running
Canceling
**Listener**
Cancelled
在这个例子中,我允许任何改变在myMethod
里面,剩下的就是提供给我的。
public static void main(String[] args) {
Runnable task = new Runnable() {
public void run() {
try {
System.out.println("Task Started");
interruptableWork();
System.out.println("Task Completed");
} catch (InterruptedException e) {
System.out.println("Task Canceling");
cleanup();
System.out.println("Task Cancelled");
Thread.currentThread().interrupt();
}
}
private void interruptableWork() throws InterruptedException {
TimeUnit.SECONDS.sleep(2);
}
private void cleanup() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException ignored) {
}
}
};
Runnable listener = new Runnable() {
public void run() {
System.out.println("**Listener Started**");
}
};
ExecutorService executor = Executors.newCachedThreadPool();
Future<?> future = myMethod(task, listener, executor);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException ignored) {
}
future.cancel(true);
}
private static Future<?> myMethod(Runnable task, Runnable listener, ExecutorService executor) {
ListeningExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor);
ListenableFuture<?> future = listeningExecutor.submit(task);
future.addListener(listener, executor);
return future;
}