Jak o:
zgłosić swoją Callable
do ExecutorService
i trzymać rączkę do zwracanego Future
.
ExecutorService executorService = ... // Create ExecutorService.
Callable<Result> callable = new MyCallable(); // Create work to be done.
Future<Result> fut = executorService.submit(callable);
zawinąć Future
w realizacji Delayed
czym Delayed
„s getDelay(TimeUnit)
metoda zwraca maksymalny czas wykonania danej pracy.
public class DelayedImpl<T> implements Delayed {
private final long maxExecTimeMillis;
private final Future<T> future;
public DelayedImpl(long maxExecTimeMillis, Future<T> future) {
this.maxExecMillis = maxExecMillis;
this.future = future;
}
public TimeUnit getDelay(TimeUnit timeUnit) {
return timeUnit.convert(maxExecTimeMillis, TimeUnit.MILLISECONDS);
}
public Future<T> getFuture() {
return future;
}
}
DelayedImpl impl = new DelayedImpl(3000L, fut); // Max exec. time == 3000ms.
Add the `DelayedImpl` to a `DelayQueue`.
Queue<DelayedImpl> queue = new DelayQueue<DelayImpl>();
queue.add(impl);
mają gwint wielokrotnie take()
z kolejki i sprawdzić, czy każdy DelayedImpl
„s Future
jest zakończona przez wywołanie isDone()
; Jeśli nie, anuluj zadanie.
new Thread(new Runnable() {
public void run() {
while (!Thread.interrupted) {
DelayedImpl impl = queue.take(); // Perform blocking take.
if (!impl.getFuture().isDone()) {
impl.getFuture().cancel(true);
}
}
}
}).start();
Główną zaletą tego podejścia jest to, że można ustawić inny maksymalny czas wykonania za zadanie i kolejki opóźnienia automatycznie powróci zadanie z najmniejszą ilość czasu wykonania pozostały.
Future.get (długi limit czasu, jednostka TimeUnit), który rzuca TimeoutException na pewno to zrobi? Przypuszczam, że w haczyku na ten wyjątek nazywasz future.cancel (true) ... – JeeBee
Future.get (long, TimeUnit) będzie blokować do określonego czasu dla tego * konkretnego * Future to complete. Jednak dodane przeze mnie rozwiązanie pozwala na sprawdzenie pojedynczego wątku * wszystkich * Aktywnych kalek, zamiast * blokowania * na konkretnym. Załóżmy, że przesyłam żądanie, które powinno zająć 5 minut; w moim wątku "check" wywołuję future.get (5L, TimeUnit.MINUTES). Następnie przesłana zostanie kolejna wersja z maksymalnym czasem wykonania 10 sekund. Jednak wątek nie będzie sprawdzał, czy ten drugi tryb wywoływania działa przez> 10 sekund, dopóki nie powróci poprzednie wywołanie blokujące. – Adamski