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;
}