web-dev-qa-db-ja.com

TimerTask vs Thread.sleep vs Handler postDelayed-Nミリ秒ごとに関数を呼び出すのが最も正確ですか?

Nミリ秒ごとに関数を呼び出す最も正確な方法は何ですか?

  • Thread.sleepを持つスレッド
  • TimerTask
  • PostDelayedを使用するハンドラー

この例 Thread.sleepを使用して変更しましたが、あまり正確ではありません。

特定のBPMでサウンドを再生する音楽アプリを開発しています。完全に正確なメトロノームを作成することは不可能であり、その必要はありません-これを行うための最良の方法を探しているだけです。

ありがとう

54
fxfuture

タイマーを使用することにはいくつかの欠点があります

  • タスクを実行するために単一のスレッドのみを作成し、タスクの実行に時間がかかりすぎると、他のタスクが影響を受けます。
  • タスクによってスローされた例外を処理せず、スレッドが終了するだけで、他のスケジュールされたタスクに影響し、実行されません

ScheduledThreadPoolExecutorはこれらすべての問題を適切に処理し、Timerを使用することは意味がありません。あなたのケースで使用できる2つのメソッドがあります。

class MyTask implements Runnable {

  @Override
  public void run() {
    System.out.println("Hello world");
  } 
}

ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
long period = 100; // the period between successive executions
exec.scheduleAtFixedRate(new MyTask(), 0, period, TimeUnit.MICROSECONDS);
long delay = 100; //the delay between the termination of one execution and the commencement of the next
exec.scheduleWithFixedDelay(new MyTask(), 0, delay, TimeUnit.MICROSECONDS);
59
Amol Sonawane

On Android独自のハンドラー/メッセージキューを使用してスレッドを作成できます。非常に正確です。Handler documentation を見ると、そのために設計されていることがわかります。

ハンドラーの主な用途は2つあります:(1)メッセージとランナブルが将来のある時点で実行されるようにスケジュールするため;と(2)に自分とは異なるスレッドで実行されるアクションをキューに入れます。

7
mleczey

それらはすべて精度に関して同じです。 Javaタイミングの精度は、システムタイマーとスケジューラの精度と精度の影響を受け、保証されません。Thread.sleepおよびObject.wait APIを参照してください。

1