web-dev-qa-db-ja.com

Java-thread.sleepの代替

Whileループを特定のミリ秒数一時停止する必要があります。 Thread.sleep(duration)を使用してみましたが、特にループシナリオでは正確ではありません。私のプログラムではミリ秒の精度が重要です。

これは、expectedElapsedTimeが通過するまで条件のチェックに戻りたくないアルゴリズムです。

while (condition) {
    time = System.currentTimeMillis();
    //do something
    if (elapsedTime(time) < expectedElapsedTime) ) {
        pause the loop  // NEED SUBSTITUTE FOR Thread.sleep()
    }
    // Alternative that I have tried but not giving good results is 
    while ((elapsedTime(time) < expectedElapsedTime)) {
        //do nothing
    }
}

long elapsedTime(long time) {
   long diff = System.currentTimeMillis() - time;
   return diff;
}
21
user1189747

ScheduledThreadPoolExecutor を試してください。より信頼できるタイミング結果が得られるはずです。

10
Bill

何を期待していますか?

スリープ状態になると、プロセスが再び実行可能になると、スレッドスケジューラが再度スケジュールするのを待つ必要があります。

つまり、50秒間スリープ状態になっても、プロセスが正確に50秒で実行されるわけではありません.aterが起動して実行可能であるため、CPUにスケジュールされるまで待機する必要があります。コンテキスト切り替えのために持っています。

それを制御するためにあなたができることは何もないので、あなたが言っている正確さを持つことができません。

あなたの場合、代わりに回転ループをお勧めします。

long now = System.currentTimeMillis();   
while(now < expectedElapsedTime){
    now = System.currentTimeMillis();
}
10
Cratylus

Javaはリアルタイムシステムではないため、スレッドを削除して、このような厳しいスケジュールに戻すことはできません。プログラムの実行をミリ秒までスケジュールするには、 simpleRTJ または Java Real-Time extension のような別のプラットフォームを使用する必要があります。

7
jprusakova

遅延は任意に選択される可能性が高いため、リアルタイムインターバルタイミングの必要性について質問します。

読み取り時間を必要とする場合は、時間に達するまでビジー状態にする必要があります。 CPUをあきらめると、必要なときに正確にCPUが返されることを保証できません。

2
Peter Lawrey

待機/通知メカニズムを実装し、待機状態にある他のスレッドに時間が経過したこと、および進行できることを通知する責任を別のスレッドに委任できます...

たとえば、threadAが特定の時間待機する必要がある場合、スレッドを待機状態にして、一定の時間(間隔)の呼び出しの後に通知するタイマータスクを開始し、先に進むThreadAをウェイクアップすることができます。代替です。

1
aleroot

解決策は、実行可能なハンドラーと 'postDelayed'メソッドを使用することです。例:

new Handler().postDelayed(new Runnable() {
public void run () {
    // Do delayed stuff!
}
}, 5000L); //5 seconds delay 

https://stackoverflow.com/a/21680858

1
Android Freaks

サウンドを正確にしたい場合は、シーケンサーを使用し、BPMでテンポを設定します。sequencer.setTempoInBPM(120);

1
user1938065

ガベージコレクターの一時停止を忘れないでください。それはあなたのすべての計画を打ち負かすことができます

0
user2737635