私は使用しますScheduledExecutorService
- タスクが1秒で発生するようにスケジュールし、すでにスケジュールされているタスクがある場合はそれをキャンセルし、新しいタスクが1秒で発生するようにスケジュールします
このようにして、最後にイベントがトリガーされてから 1 秒後にタスクが実行されます。
private class Task implements Runnable {
@Override
public void run() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
private Future<?> scheduledTaskHandle;
private class Listener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (scheduledTaskHandle != null && !scheduledTaskHandle.isDone()) {
scheduledTaskHandle.cancel(false);
}
scheduledTaskHandle = executorService.schedule(new Task(), 1, TimeUnit.SECONDS);
}
}
はTask
、Runnable
長時間実行される操作を行う です。これListener
はリスナークラスです。
このListener.actionPerformed
メソッドでは、最初に を使用してタスクが既にスケジュールされているかどうかを確認し、スケジュールされているFuture
場合はキャンセルします。ここで競合の危険性について心配する必要はありません。タスクが の呼び出しisDone
と の呼び出しの間に終了した場合、cancel
何も起こりません。
が起動した時点でタスクが実行されている場合、でメソッドが呼び出されるListener
ため、そのタスクは完了します。別のタスクは、リスナーの起動の 1 秒後、または現在実行中のタスクが完了すると実行されるようにスケジュールされます (実行できるタスクは 1 つしかないため、単一のスレッドのみを使用しているため)。cancel
false
次にListener
、タスクの新しい実行が 1 秒で発生するようにスケジュールします。