2

次のコードがあります。

public class ThreadTest implements Runnable {
    public int ThrCount    = 0;

    public void ThrCountIncr() {
        while (true) {
            ThrCount++;
            System.out.println(ThrCount);
            try {
                Thread.currentThread().sleep(500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public void run() {
        while (true) {
            if (ThrCount > 10) {
                System.out.println(ThrCount + "\n Thread finished");
                System.exit(1);
            }
            try {
                Thread.currentThread().sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

しかし、この行を から削除するとrun、動作しなくなります:

Thread.currentThread().sleep(100);

まず、スレッドを開始し、次に を使用しますThrCountIncr

ThreadTest Thrtest = new ThreadTest();
Thread thr = new Thread(Thrtest);
thr.start();
Thrtest.ThrCountIncr();

スレッドはThrCount変数値をチェックし、10 より大きい場合はプログラムを停止します。がないsleep(100)と、スレッドはプログラムを停止せず、変数の値をチェックしないと思います。sleepこのコードを実行するための呼び出しが機能するのはなぜですか?

4

3 に答える 3

11

であっても、Thread.sleep()動作しない場合があります。ThrCountこれは、共有変数へのアクセスを適切に同期していないためです。

その variable を作成するとvolatile、問題は発生しなくなります。++ただし、操作はアトミックではないため、正確に 10 回ループしない場合があります。

理想的には、AtomicInteger を使用し、そのincrementAndGet()メソッドを使用する必要があります。

また、次の点に注意してください。

  • Java の命名規則: 変数とメソッド名は小文字で開始する必要があります ( thrCount,thrCountIncr()
  • sleepは静的メソッドであるため、単純に呼び出すことができThread.sleep(...);、現在のスレッドでスリープします。
于 2012-11-13T16:44:52.640 に答える
4

スレッドがスリープ状態にならない場合、他のスレッドが機能しない可能性があるため、内部のループがThrCountIncrいつでもスタックする可能性があります (おそらく最初sleepまたは でprintln)。

スリープや待機なしでスレッドがループすることはありません。

ThrCount++;アトミック操作ではないため、同期を使用して保護しないと失敗する可能性があることにも注意してください。

于 2012-11-13T16:44:33.483 に答える
3

ループが 10,000 回以上繰り返された場合、JIT によって最適化できます。2 番目のスレッドの場合、スレッドのコードはフィールドを変更しないため、JIT はif条件を最適化するか、常に実行することを決定できます。

フィールドを作成volatileすると、JIT がそのような最適化を行うことができなくなります。

于 2012-11-13T16:59:05.913 に答える