0

誰かがこのコードを説明できますか?

public class Main implements Runnable{

private int i;
public synchronized void run() {
    System.out.print("i = "+ i +"\n");
    if (i % 5 != 0) {
        i++;
    }
    for (int x = 0; x < 5; x++, i++) {
        if (x > 1) {
            Thread.yield();
        }
    }
}

 public static void main(String[] args) {
    Main n = new Main();
    for (int x = 100; x > 0; --x) {
        new Thread(n).start();
    }
}
}

そして出力はどうですか

i= 0
i= 5
i= 10
i= 15
i= 20
.
.
.
i= 499
4

3 に答える 3

3

下のループは100個のスレッドを作成します。各スレッドは、他のスレッドと並行してすぐに実行されます。各スレッドで、

  • 開始時に、共有属性「i」の現在の値が出力されます
  • iが5で割り切れない場合は、1回インクリメントされます
  • 次に、最大5回ループが実行されます。最後の3回実行されると、他のスレッドに譲ります。このループが実行されるたびに、共有変数'i'がインクリメントされます。

したがって、iは5で割り切れる場合は5倍、そうでない場合は6倍になります。ただし、run()メソッドは同期されています。したがって、他のスレッドの1つがすでに実行されている間は、他のスレッドの実行は許可されません。プログラムは事実上シングルスレッドであり、yield()は無視され(他のスレッドは実行できません)、出力は次のようになります。

for (int i=0; i<500; i+= 5) System.out.println(i);
System.out.println(499);

同期を削除して、出力を変更するあらゆる種類の競合状態を確認します。

于 2013-01-12T12:51:42.613 に答える
2

メインスレッドは100個のスレッドを作成し、各スレッドは同期メソッドを実行して、実行をシリアル化します。すべてのスレッドはiの現在の値(最初はデフォルトで0)を出力し、5倍にインクリメントして、次のcpuを取得する(そして本体を実行する)スレッドが新しい値のを出力するようにしますi

Thread.yield(); CPUを放棄しますが、ロックを解除することを意味するものではありません。そのため、各スレッドはrun前のスレッドが終了した後にメソッドを実行し、それ以外の場合は実行しません。

于 2013-01-12T12:41:09.413 に答える
1

yieldモニターを解放しないことを理解することが重要です。したがって、すべてのスレッドは順番に実行されます。つまり、ブロック内にあり、モニターがロックされたままyieldであるため、他のスレッドの実行は許可されません。synchronized

于 2013-01-12T12:52:55.247 に答える