1

このプログラムが出力9を提供している理由を誰でも説明できますか?メインスレッドとスレッド0は任意の順序で実行できるため、その答えとして「予測できない動作」を推測しました。join()はメインスレッド自体で何をしますか?

public class Starter extends Thread{
    private int x = 2;
    public static void main(String[] args) throws Exception{
        new Starter().makeItSo();
    }

    public Starter(){
        //Thread main
        x=5;
        start();
    }

    public void makeItSo() throws Exception{
        //Thread main
        join();
        x = x-1;
        System.out.println(x);
    }

    public void run(){ 
        //Thread-0
        x*= 2;
        }
}

メインスレッドはthread-0を開始し、runメソッドを呼び出します。しかし、makeItSo()にSOPを入れると、join()の呼び出し後にメインスレッドがそこで待機していることが示されます。なぜ?makeItSo()とrun()の間にシーケンスがないので、Xの値は予測できません。

4

4 に答える 4

6

への呼び出しのため、ここでの実行順序は固定されていますjoin()

  1. コンストラクターは を設定しますx = 5
  2. コンストラクターは、新しいスレッドstartを呼び出します。run
  3. runを実行しx *= 5x10 に等しくします。
  4. makeItSoと呼ばれます。を呼び出しjoinて、終了を待ちrunます。
  5. 最後に、を9にmakeItSo設定します。x = x-1x
于 2013-01-14T16:37:59.593 に答える
1

これを本当に深く理解するには、次17.4.4 Synchronization Orderのように Java 言語仕様を読む必要があります。

Synchronization actions induce the _synchronized-with_ relation on actions, 
defined as follows:   
         ...
 - An action that starts a thread _synchronizes-with_ the first action in the 
thread it starts.
         ...
 - The final action in a thread *T1* _synchronizes-with_ any action in another
thread *T2*  that detects that *T1* has terminated. *T2* may accomplish this 
by calling *T1.isAlive()* or *T1.join()*.
于 2013-01-14T16:44:52.573 に答える
0

この混乱は、join() の呼び出し方法が原因であると考えています。これは、インスタンス メソッドから呼び出されるため、this.join() と言うようなものです。「this」は、メイン メソッドで作成された Starter オブジェクトを参照します。

これは、メイン スレッドがスターター スレッドが終了するのを待ち、その後 x の値を減らすことを意味します。これにより、結果が非​​常に予測可能になります。

于 2013-10-30T18:06:00.337 に答える
0

最初に Starter オブジェクトを作成します。コンストラクターにはx = 5. あなたが呼び出すよりもstart()、内部的に呼び出しますrun()。実行後、x は 10 ( x *= 2) です。join()終了するのを待ってrun()います。その後、x を 1 減らします。それだけです。x は 9 です。ここで予測できないことは何もありません。

于 2013-01-14T16:37:07.890 に答える