2017-06-26 8 views
4

シンプルなプログラムを書いたところ、JVisualVMを実行するにはスレッドが速すぎて、監視したいアプリケーションをマークし、プラグインしてスレッドを見ていることに気付きました。私は彼らを眠らせた。そして注目されたツールは、眠っている(またはほとんど眠っていない)と報告しています。彼らは働いていますが。これは質問をする:なぜ?スレッドが長時間スリープする

new Thread(() -> { 
     while(true) { 
      System.out.println("not sleeping"); 
      try { 
       Thread.sleep(0,1); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    }, "not sleeping!").start(); 

このスレッドは、1ナノ秒のために寝る必要があり、まだそれはJVisualVMによって報告されます方法を見取る:それは5Sは睡眠のように、時間と休息を実行している報告57Sのために実行した後

ran for a minute but ran 5s

を - バグか私の理解は間違っていますか?

それだけではありませんJVisualVM:

$ while true; do jstack 8277 | grep -A 2 not; done    [% 20:34:27] 
"not sleeping!" #10 prio=5 os_prio=0 tid=0x00007f5ea82d1000 nid=0x2078 waiting on condition [0x00007f5e917c6000] 
    java.lang.Thread.State: TIMED_WAITING (sleeping) 
    at java.lang.Thread.sleep(Native Method) 

jstackもたまにしかRUNNINGとしてこのスレッドを報告します。私は異なる比率を期待していますので、理解してください。

+0

指定した時間だけスリープしているスレッドに頼ることはできません。 57sは...しかし、過剰です。 –

+0

@AndyTurner私は同意します。ナノといっしょに。しかし、私はその割合が...まあ、逆転するとは期待していませんでした。それはほとんどが眠っている。 –

答えて

1

1ナノ秒ほど短いとは思えません。あなたがスリープ状態を要求すると、タスクスイッチが実行され、特に他のプロセスやスレッドがある場合は、スケジュールを取るまでに時間がかかります。スレッドの作業負荷が非常に低い場合、ほとんどの場合、スリープ状態になることがあります。

スリープ時間は、システムの時間単位の倍数にあるレイヤーで切り上げられる可能性もあります。少なくともいくつかのJava実装では、nanos引数is mostly ignoredがあります。

+0

私は最小限にするために1 nsを要求しました。私は1nsを期待したことはありません。なぜなら、nanosがシステムに依存しているドキュメントでは、ほとんどすべてのJavaメソッドがnanos状態であるからです。それにもかかわらず、それがそうであるかどうかを確認したい他の人には、コンテキストスイッチの数を調べる(/ procからpidstatまたはcat thread status)。ソースリンクと答えをありがとう!作業量を増やすと(ランダムnのためのフィボナッチ)、スレッドは主に実行可能になりました。 –

関連する問題