3

Object.wait(timeout)Androidアプリサービスで使用しました。ただし、「ディープ スリープ モード」で費やされた時間はカウントされません。AlarmManager を使用してアプリを定期的に起動するので、ディープ スリープからの復帰は問題になりません。問題は、wait(60000)100 秒のディープ スリープ後に終了しないことです。

SystemClockヘルプ ページで読んだように、ディープ スリープでカウントを停止するuptimeMillis()object.waitメソッドを使用します。私のニーズでは、lapsedRealtime()を使用することをお勧めします。

Object.wait(timeout)アナログを実装するにはどうすればよいですか?または、代わりに何を使用できますか?


この方法を使用するタスクの 1 つは、他のパケットがキューにしばらく入っていないときにネットワーク経由で送信する「ping」パケットを生成することです。

4

3 に答える 3

1

プレーンな Object.wait() または Thread.sleep() を使用する代わりに、次のいずれかを使用することをお勧めします。

  1. 一定の間隔または遅延でタスクをスケジュールできる java.util.concurrent.newScheduledThreadPool を使用します。threadCount = 1 でスレッド プールを初期化すると、単一のスレッドが得られます。

  2. TimerTask をスケジュールできる java.util.Timer を使用します。

1.が好ましい方法だと思います。

タイマー オブジェクトをプラグインするか、特定のまたはサード パーティのタイミング プロバイダーを使用するという特定の要件がある場合は、ScheduledExecutorService をラップする独自のスケジューラーを記述し、独自のタイマーを使用して時間を変換するか、自分のタイマーから時間を取得します。基本的に、ラップされたサービスでスケジュールされたタスクを独自の時間計算で起動します。

以下のように、アクター モデルにそのようなスケジューラのサンプルがあります。このパッケージの DefaultScheduler を見てください。少しバグがあるかもしれませんが (まだ完全にはテストしていません)、良いアイデアが得られるはずです。

http://sourceforge.net/p/jalgo/code-0/HEAD/tree/trunk/src/org/as/algo/threading/

于 2013-10-28T03:29:22.000 に答える
0

それがまさにあなたが望んでいることをするかどうかはわかりませんが、私はこれを書いて一定期間一時停止しますが、他のスレッドが私を時期尚早に目覚めさせるようにします.

内部で を使用しBlockingQueueて睡眠を行うため、使用sleepを避けwait、それらに伴うすべての悲しみを回避します。

Android でどのように動作するかはわかりません。私はそれを使用していませんが、既存のAlarmManager作業が適応すると思われます。

/**
 * Use one of these to doze for a certain time.
 *
 * The dozing is fully interruptable.
 *
 * Another thread can stop the caller's doze with either a wakeup call or an abort call.
 *
 * These can be interpreted in any way you like but it is intended that a Wakeup is
 * interpreted as a normal awakening and should probably be treated in exactly the
 * same way as an Alarm. An Abort should probably be interpreted as a suggestion
 * to abandon the process.
 */
public class Doze {
  // Special alarm messages.
  public enum Alarm {
    // Standard timeout.
    Alarm,
    // Forced wake from your doze.
    Wakeup,
    // Abort the whole Doze process.
    Abort;
  }
  // My queue to wait on.
  private final BlockingQueue<Alarm> doze = new ArrayBlockingQueue<>(1);
  // How long to wait by default.
  private final long wait;

  public Doze(long wait) {
    this.wait = wait;
  }

  public Doze() {
    this(0);
  }

  public Alarm doze() throws InterruptedException {
    // Wait that long.
    return doze(wait);
  }

  public Alarm doze(long wait) throws InterruptedException {
    // Wait that long.
    Alarm poll = doze.poll(wait, TimeUnit.MILLISECONDS);
    // If we got nothing then it must be a normal wakeup.
    return poll == null ? Alarm.Alarm : poll;
  }

  public void wakeup() {
    // Just post a Wakeup.
    doze.add(Alarm.Wakeup);
  }

  public void abort() {
    // Signal the system to abort.
    doze.add(Alarm.Abort);
  }

  private static long elapsed ( long start ) {
    return System.currentTimeMillis() - start;
  }

  // Test code.
  public static void main(String[] args) throws InterruptedException {
    // Doze for 1 second at a time.
    final Doze d = new Doze(1 * 1000);
    final long start = System.currentTimeMillis();

    // Start a dozing thread.
    new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          Alarm a = d.doze();
          // Wait forever until we are aborted.
          while (a != Alarm.Abort) {
            System.out.println(elapsed(start) + ": Doze returned " + a);
            a = d.doze();
          }
          System.out.println(elapsed(start) + ": Doze returned " + a);
        } catch (InterruptedException ex) {
          // Just exit on interrupt.
        }
      }

    }).start();


    // Wait for a few seconds.
    Thread.sleep(3210);

    // Wake it up.
    d.wakeup();

    // Wait for a few seconds.
    Thread.sleep(4321);

    // Abort it.
    d.abort();


  }

}
于 2013-10-30T09:19:58.050 に答える