у меня есть:Run слушателем, когда задача возвращает
ExecutorService
что кто-то предоставил.- A
Runnable
Задача, которая очищается после себя, когда она прерывается. Runnable
слушатель
Моя работа состоит в том, чтобы выполнить задачу на ExecutorService
и затем запустить слушателя на том же ExecutorService
через некоторое время после того как задача вернулась, либо нормально (через return
) или бросать исключение. Я возвращаюсь к своему клиенту Future
, и он (иногда) звонит cancel(true)
.
Моя первая мысль заключалась в использовании Guava's 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;
}