質問については、タイムアウトで何をしたいのか明確ではありません。ここでは、軽量タイムアウトを実装するための 2 つのオプションを紹介します。監視と制御です。
監視タイムアウト
グローバル タイマーの場合Timer
、JDK の機能を使用できます。
public TimeoutTask implements TimerTask {
List<MonitorableObject> objects;
public TimeoutTask(List<MonitorableObject> objects) {
// make sure you can share this collection concurrently,
// e.g. copyonwritearraylist
this.objects = objects;
}
public void run() {
// objects -> filter(isTimeOut(currentTime)) -> do something
}
}
Timer timer = new Timer();
timer.schedule(new TimeoutTask(myObjectList), 0,60*1000); // repeat each 60secs
を使用して同様の構成が可能ScheduledExecutorService
です:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
// Note that I can use here TimeoutTask b/c TimerTask is a Runnable -
// this is just for the example. You'd better implement a plain runnable.
scheduler.schedule(new TimeoutTask(myObjectList), 60, TimeUnit.SECONDS);
スレッドのプールを保持できるため、私はScheduledExecutorService
上記のTimer
機能を好みます。SchedulerExecutor
また、基になるスレッドプールはscheduledExecutorService.execute(...)
、即時の同時実行 (スケジュールされていない) を呼び出す他の操作に使用できるため、専用のタイマー関数ではなく、汎用のエグゼキューター機能になります。
どちらの場合も、監視しているオブジェクトからタイムアウト値を安全に取得するために特別な注意を払う必要があります。通常、オブジェクトの同期メソッドを使用して、オブジェクトのタイムアウト ステータスを要求します。
強制タイムアウト
ExecutorService は、指定されたタイムアウト内で一連のタスクを実行するための API を提供します。例えば
List<Callable<?>> myTasks = ...;
// populate myTasks with Callable`s that wrap your intended execution
ExecutorService executorService = ... ;
List<Future<?>> results = executorService.invokeAll(myTasks, 60, TimeUnit.SECONDS);
このメソッドが戻った後、指定された時間内に成功したかどうかをすべての Future に問い合わせることができます。