0

私はマルチスレッドが苦手です。これは基本的な質問かもしれません。しかし、私は答えを見つけることができませんでした。

シナリオ: 何かによって起動されるイベント リスナーがあるとします。イベントが発生するたびに、実行に約 3 秒かかる新しいスレッドを開始したいと考えています。

問題: 問題は、イベントが 1 秒間に複数回発生する可能性があることです。一度に複数のスレッドを開始したくありません。

要件: イベントの 1000 ミリ秒後にスレッドをスケジュールする方法を教えてください。イベントが発生し続ける場合は、スレッドの予定時刻を遅らせ続けたいと思います。このようにして、最後にイベントが発生してから 1000 ミリ秒後にスレッドが実行されます。

4

2 に答える 2

2

私は使用します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);
    }
}

TaskRunnable長時間実行される操作を行う です。これListenerはリスナークラスです。

このListener.actionPerformedメソッドでは、最初に を使用してタスクが既にスケジュールされているかどうかを確認し、スケジュールされているFuture場合はキャンセルします。ここで競合の危険性について心配する必要はありません。タスクが の呼び出しisDoneと の呼び出しの間に終了した場合、cancel何も起こりません。

が起動した時点でタスクが実行されている場合、でメソッドが呼び出されるListenerため、そのタスクは完了します。別のタスクは、リスナーの起動の 1 秒後、または現在実行中のタスクが完了すると実行されるようにスケジュールされます (実行できるタスクは 1 つしかないため、単一のスレッドのみを使用しているため)。cancelfalse

次にListener、タスクの新しい実行が 1 秒で発生するようにスケジュールします。

于 2013-04-01T16:02:48.197 に答える