これは私が思いついた解決策です。それはかなりシンプルなようですが、私はまだそこにもっと一般的な、そして/またはエレガントな解決策があると仮定します。そして、私は私のコールバックを発射するラッパーを作成
private static final class SynchronizedRunnable implements Runnable {
private final Object monitor;
private final Runnable delegate;
private SynchronizedRunnable(Object monitor, Runnable delegate) {
this.monitor = monitor;
this.delegate = delegate;
}
@Override
public void run() {
synchronized (monitor) {
delegate.run();
}
}
}
:私は本当に私は私のランナブルで相互排他を課すためのラッパーを作成まず
...グアバなどのライブラリに1を見てみたいと思います
cancel
の成功invokations:
private static final class FutureWithCancelCallback<V> extends ForwardingFuture.SimpleForwardingFuture<V> {
private final Runnable callback;
private FutureWithCancelCallback(Future<V> delegate, Runnable callback) {
super(delegate);
this.callback = callback;
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
boolean cancelled = super.cancel(mayInterruptIfRunning);
if (cancelled) {
callback.run();
}
return cancelled;
}
}
その後、私は私自身の方法で一緒にそれをすべてロール:
private Future<?> scheduleWithFixedDelayAndCallback(ScheduledExecutorService service, Runnable work, long initialDelay, long delay, TimeUnit unit, Runnable cleanup) {
Object monitor = new Object();
Runnable monitoredWork = new SynchronizedRunnable(monitor, work);
Runnable monitoredCleanup = new SynchronizedRunnable(monitor, cleanup);
Future<?> rawFuture = service.scheduleAtFixedRate(monitoredWork, initialDelay, delay, unit);
Future<?> wrappedFuture = new FutureWithCancelCallback(rawFuture, monitoredCleanup);
return wrappedFuture;
}
私はexecutorサービスのすべてのタスクをキャンセルするつもりはありません...私はスケジュールされたタスクだけをキャンセルします。実際、ScheduledExecutorServiceは私に提供されており、他の誰がタスクをサブミットしているのかわかりません。 – Drew
ああ、残念です...それは、 'ScheduledExecutorService'を拡張してしまい、より多くの選択肢があります。あなたの '仕事'インスタンスはどうですか?それはあなたの手にありますか? – skirsch
はい、作業とクリーンアップのタスク/ Runnablesは私のものです。私は作業/クリーンアップのビジネスロジックからスレッド/エグゼキュータの懸念を分離したいと思います...これらのクラスをいくつかのTaskから継承させてもらえれば幸いです。あるいは、他の実行可能/呼び出し可能なクラスでそれらをラップすることもできます。 – Drew