0

これは私の簡単なプログラムです:

public class Test {
    public static Object obj = null;

    public static void main(String[] args) {
        obj = null;
        System.out.println("Start");
        MyThread myThread = new MyThread();
        myThread.start();
        while(obj == null) {
            //System.out.println("");
        }
        System.out.println("Stop");

    }
}

class MyThread extends Thread {

    @Override
    public void run() {
        System.out.println("Thread 1");
        try {
            sleep(1);
        } catch (InterruptedException ex) {
        }
        System.out.println("Thread 2");
        Test.obj = new Object();
        System.out.println("Thread 3");
    } 
}

ご覧のとおり、MyThread スレッドと Test クラスの while ループを実行します。ループは obj が null かどうかをチェックし、そうでない場合は停止して "2" を出力します。MyThread は obj に値を割り当てます。そして今問題:

Java 7 64 ビットでは、空の while ループの場合、ループは停止しません。ただし、System.out.print("") のコメントを外すと、ループの下の "Stop" が出力されます。しかし、ループ内の他のステートメント (int i = 1; など) では、プログラムがフリーズします。Java 32 ビットでは、すべてのケースで問題なく動作します。

誰かが私にこの奇妙な行動を説明してもらえますか?

ありがとう!

4

2 に答える 2

3

あなたのコードはスレッドセーフではありません。スレッドで行った割り当てはTest.obj、何らかの形式の同期なしではメイン スレッドで表示されるとは限りません。

その静的変数をプライベートにし、同期された静的 getter/tester/setter メソッドを提供することは、これを正しく実装する 1 つの方法です (すべてのアクセスがこれらのメソッドを経由する限り)。他の代替手段が存在します。

于 2012-05-18T08:24:33.647 に答える
2

Javaにもvolatileキーワードがあることに注意してください。この特定の例の場合、Java はobj.

于 2012-05-18T08:26:44.370 に答える