Wie wäre es damit:
Senden Sie Ihr Callable
au ExecutorService
und ein Handle auf den zurückgegebenen Future
.
ExecutorService executorService = ... // Create ExecutorService.
Callable<Result> callable = new MyCallable(); // Create work to be done.
Future<Result> fut = executorService.submit(callable);
Wickeln Sie die Future
in einer Implementierung von Delayed
wobei Delayed
's getDelay(TimeUnit)
Methode gibt die maximale Ausführungszeit für die betreffende Arbeit zurück.
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);
Wiederholt einen Faden haben take()
aus der Warteschlange und prüfen, ob jeder DelayedImpl
's Future
ist abgeschlossen durch den Aufruf von isDone()
Wenn nicht, brechen Sie die Aufgabe ab.
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();
Der Hauptvorteil dieses Ansatzes ist, dass Sie eine unterschiedliche maximale Ausführungszeit pro Aufgabe und die Verzögerungswarteschlange wird automatisch die Aufgabe mit der geringsten verbleibenden Ausführungszeit zurückgeben.