3

プロパティを使用して「アイドル待機」モデルを実行するにはどうすればよいですか。

  • メソッドdo()が呼び出されると、X遅延後、close()メソッドが呼び出されます。
  • X時間が経過するdo()にメソッドを再度呼び出すと、への呼び出しを延期する必要があります。close()

シナリオ1:(タイムアウト=10秒の場合):

  1. ユーザーはdo()時間に電話をかけ0ます。
  2. の時点10で、ユーザーが再度呼び出していないため、close()メソッドが呼び出されdo()ます。

シナリオ2:(タイムアウト=10秒):

  1. ユーザーはdo()時間に電話をかけ0ます。(したがって10close()メソッドで呼び出す必要があります)。
  2. の時点で8、ユーザーはdo()再度電話をかけます。
  3. が10秒延期された10ため何も起こらない時。close()
  4. の時点で、ユーザーが。以降に再度呼び出していないため18close()メソッドが呼び出されます。do()8

私が試したこと:

private static final long delay = 10000;
private Timer t;
private TimerTask tt;

public void do() {

    ...

    // check old timer first:
    if (t != null) t.cancel();

    // create new timer
    t = new Timer();
    tt = new TimerTask() {
        @Override
        public void run() {
            close();
        }
    }
    // run it
    t.schedule(tt, System.currentTimeMillis() + delay);
}
private void close() {
    // do some cleanup here
}

このコードは非常に醜いです。また、 do()関数が1秒間に約50回呼び出されるため、非常に非効率的でメモリを消費します。

これを効率的かつきちんと機能させるにはどうすればよいですか?(本当に大変ですか?)

4

3 に答える 3

4

あなたは正しい道を進んでおり、難しい道ではありません。

これが私があなたに提案したいことです。タイマーを一度だけ作成します。クラスのメンバーにします。コンストラクターでそのインスタンスを作成します。

メソッドが呼び出されたら、既に行っているようにタスクを作成します。ただし、別のクラスを作成し、事前にインスタンスを作成することもできます。do()メソッドが呼び出されたときにスケジュールするだけなので、close()スケジュールに従って呼び出されます。

do()呼び出されると、以前に作成されたクローズ タスクがキャンセルされます。do()これにより、メソッドが再度呼び出された場合に何も閉じないことが保証されます。

ところで、doJava の予約語であるため、この方法でメソッドを呼び出すことはできません。これは、コードをコンパイルすることさえできないことを意味します。名前を変更します。

于 2013-03-21T20:19:12.287 に答える
1

10 秒のタイマー タスクを設定すると、open()

からlong lastCall設定される変数を保持するSystem.currentTimeMillis()doIt()

time タスク本体で、lastCall10 秒以内かどうかを確認します。その場合は、タイマー タスクを残りの時間に再スケジュールします。そうでない場合は、電話してくださいclose()

synchronize読み書きするときは on 何かを忘れないでくださいlastCall

于 2013-03-21T20:26:59.293 に答える
0

私は適切な解決策を見つけました:

public class TimerExample {

    private TimerTask tt;
    ScheduledFuture<?> future;
    private ScheduledThreadPoolExecutor s;

    public TimerExample() {
        s = new ScheduledThreadPoolExecutor(1);
        tt = new TimerTask() {

            @Override
            public void run() {
                close();
            }
        };
        doSomething();
    }

    public void doSomething() {
        if (future != null) future.cancel(true);
        future = s.schedule(tt, 3000, TimeUnit.MILLISECONDS);
        System.out.println("do");
    }

    public void close() {
        System.out.println("Close");
    }

}
于 2013-03-21T21:08:54.107 に答える