0

Thread に次のループがあると仮定しましょう ( Thread-Aと呼びましょう)。

while (threadCondition) {
  System.out.println(new Date());
  Thread.sleep(1000);
}

そして、他のThread-Bが原因で、アプリケーションが 2 秒以上ハングアップすると想定します (他のスレッドが原因です (十分な CPU リソースがない、使用可能なメモリが少ないなどの理由で、 それをThread-Bと呼びましょう)。)

Thread-Aが2 秒以上言及された後System.out.println(new Date())に実行されると、2 度続けて (「即座に」、スリープなしで) 実行され、同じ日付 (同じ番号で) が出力される可能性はありますか?ミリ秒の) 2 回?

4

5 に答える 5

3

JVM はスリープ時間の精度を保証しません。996 ミリ秒、1003 ミリ秒、または 2000 ミリ秒後にウェイクする場合があります - すべて有効な時間です

ただし、これらのスリープ時間は、基盤となる OS によって提供される機能によって制限されるため、正確であるとは限りません。また、後のセクションで説明するように、スリープ期間は割り込みによって終了できます。いずれにせよ、スリープを呼び出すと、指定された正確な期間だけスレッドが中断されるとは限りません -- source

スレッドが実際にスリープしていた時間は記録されません。

sleep()のスレッドが検出されると、スレッドは別の (そして、多かれ少なかれ) 1000 ミリ秒待機してからウェイクアップします。

スリープ時間は正確ではないため、10.000 時にアプリが日付を 1 回出力し、10.981 に同じ日付を再度出力する可能性があります。

また、sleep() メソッドが中断される可能性があることに注意してください。例外処理コードがこのループにある場合、スリープが中断され、例外が飲み込まれ、2 つの日付が出力される可能性があります。

于 2013-09-02T13:37:37.973 に答える
2

への 2 つの呼び出しはnew Date()、次の場合に同じ時間を与えることができます

  • 同じミリ秒の場合
  • それらがクロックの解像度内にある場合。たとえば、Windows XP では ~16 ms です。
  • NTP などによって時刻が変更された場合。たとえば、時間は逆戻りして繰り返すことができます。
  • バイトコード計測を使用して時間をオーバーライドする場合。たとえば、テスト駆動のクロックが必要なためです。
  • 2 つのスレッドが 2 秒間隔で開始し、同時に終了する場合、それらは同時に印刷できます。
  • スレッド B が最初に開始され、スレッド A が後に開始される場合、スレッド B はスレッド A の後に時間を印刷できます。
  • new Date() は、デフォルトで同じ秒に発生した場合、同じ日付を出力します。
于 2013-09-02T13:40:27.367 に答える
1

いいえ、 Thread.sleep(...) は、指定された時間、呼び出されてから実行を遅らせます。スレッドが一時的にバックグラウンドにプッシュされているために同期が取れなくなる可能性がある「現在の時刻」を追跡する内部カウンターはありません。これはあなたが考えているようです。

于 2013-09-02T13:23:03.523 に答える
1

私はそれが可能だとは思わない。

あなたが言及した理由のいずれかが原因でアプリケーションがハングアップすると、停止したコード行から実行が再開されます。

コードが原因でハングが発生し、現在は冗長になっている可能性があるという事実は関係ありません。JVMがコードを分析することを本当に期待していません...

于 2013-09-02T13:23:13.097 に答える
0

の代わりに使用しない理由System.nanoTime()(つまり、PC の高解像度パフォーマンス カウンター) date()。また、スリープをifに入れて条件を正しく記述した場合、スレッドはスリープしません。

于 2013-09-02T13:51:16.877 に答える