9

私は次のコードを書きました:

import java.util.Calendar;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

class Voter {   
public static void main(String[] args) {
    ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(2);
    stpe.scheduleAtFixedRate(new Shoot(), 0, 1, TimeUnit.SECONDS);
}
}

class Shoot implements Runnable {
Calendar deadline;
long endTime,currentTime;

public Shoot() {
    deadline = Calendar.getInstance();
    deadline.set(2011,6,21,12,18,00);
    endTime = deadline.getTime().getTime();
}

public void work() {
    currentTime = System.currentTimeMillis();

    if (currentTime >= endTime) {
        System.out.println("Got it!");
        func();
    } 
}

public void run() {
    work();
}

public void func() {
    // function called when time matches
}
}

func()が呼び出されたときに、ScheduledThreadPoolExecutorを停止したいと思います。それ以上動作する必要はありません!関数func()をVoterクラス内に配置し、ある種のコールバックを作成する必要があると思います。しかし、多分私はシュートクラスの中からそれをすることができます。

どうすれば適切に解決できますか?

4

1 に答える 1

21

を使用ScheduledThreadPoolExecutorすると、タスクをすぐに実行したり、後で実行するようにスケジュールしたりできます(定期的な実行も設定できます)。

したがって、このクラスを使用してタスクの実行を停止する場合は、次の点に注意してください。

  1. 1つのスレッドが実行を停止することを保証する方法はありません。Thread.interrupt()のドキュメントを確認してください。
  2. メソッドScheduledThreadPoolExecutor.shutdown()はタスクをキャンセルするように設定され、スレッドを中断しようとはしません。この方法を使用すると、実際には、新しいタスクの実行、およびスケジュールされているが開始されていないタスクの実行を回避できます。
  3. このメソッドScheduledThreadPoolExecutor.shutdownNow()はスレッドを中断しますが、このリストの最初のポイントで述べたように...

スケジューラーを停止したいときは、次のようなことをしなければなりません。

    //Cancel scheduled but not started task, and avoid new ones
    myScheduler.shutdown();

    //Wait for the running tasks 
    myScheduler.awaitTermination(30, TimeUnit.SECONDS);

    //Interrupt the threads and shutdown the scheduler
    myScheduler.shutdownNow();

しかし、1つのタスクだけを停止する必要がある場合はどうでしょうか。

このメソッドは、すでにスケジュールされているタスクを表すScheduledThreadPoolExecutor.schedule(...)aを返します。ScheduleFutureしたがって、ScheduleFuture.cancel(boolean mayInterruptIfRunning)メソッドを呼び出してタスクをキャンセルし、必要に応じてタスクを中断することができます。

于 2011-08-03T14:24:34.427 に答える