0


0

TimerおよびTimerTaskを使用する場合のJavaスレッドの実行順序

プロセス割り込みメカニズムとしてタイマーを使用しています。 ロジックの流れは次のとおりです。

T0:T0で新しいタイマーを作成し、T2で実行する新しいタイマータスクをスケジュールします(1秒のタスク遅延、タスクは非常に単純です-フラグ変数を設定します)

T1:メインの呼び出しスレッドで、5秒間スリープします

T2:タイマースレッドで、タスクが実行されます

T5:スリープ終了

T6:タイマーとスケジュールされたタスクをキャンセルする

コードは、私のWindowsおよびUbuntu開発環境で完全に機能します。 ただし、SLES 10ビルドサーバーで同じコードを実行すると、ログに次の実行順序が示されます。

T0:タイマーとタイマータスクが作成され、T2で実行されます

T1:メインスレッドは5秒間スリープします

T5:メインスレッドが起動する

T6:タイマーのキャンセル

T7:タスクの実行

誰がこれが起こるのかについて説明を提供できますか? どうもありがとう。

3 Answer


0


Hm. 私はあなたがそのような違いを(秒単位で?)見ていることに驚いていますが、マシンからマシン、jvmからjvmなどの実行の異なる順序を見る可能性があると思います。 特に、JITが初めてコードをコンパイルするとき、たとえば同じコードの後続の実行と比較して、たとえばコードで100〜300ミリ秒の遅延が発生する傾向があります。

「プロセス割り込みメカニズム」の意味がわかりません。 タイマータスクがスレッドを中断するということですか?

とにかく、今私が提案できるのは、代わりに `System.nanoTime()`を使用することです。 (私はそれが何かを説明するとは思わないが、深刻な測定では `System.currentTimeMillis()`の使用は推奨されない)。 JAVA_OPTSに「-server」を追加することをお勧めします。これにより、コードがJITによって最適化されたときの動作を確認できます。 また、コードを複数回実行して統計を取ることを強くお勧めします。

私があなただったら、まずこれらの小さなことをしてから、 CyclicBarrier、` CountdownLatch`のようなシンクロナイザーを使用してデバッグし、遅延が正確に発生する場所を確認します。

SLESの「バックグラウンドノイズ」(活動度)とは何ですか? OSは非常に忙しいのでしょうか?

タスクの性質は何ですか? ネットワーク/ IO関連のものですか?


0


タイムスタンプの問題であることが判明しました。 System.currentTimeMillisの代わりに新しいDate()。getTimeを使用すると、予想される実行タイムスタンプの順序が得られました。

良いアイデアをありがとう。


0


タスクが完了したら、イベントの発生を検討する必要があります。 これにより、実行順序が保証されます。