1

こんにちは、私はこのコードを持っています:

public class ThreadTester {
    public static void main(String args[]) {
        Counter c = new Counter();
        for (int i = 0; i < 10; i++) {
            MyThread a = new MyThread(c);
            MyThread b = new MyThread(c);
            a.start();
            b.start();
        }   
        System.out.println("The value of the balance is " + c.getVal());
    }
}

class MyThread extends Thread {
    private Counter c;
    public MyThread(Counter c){ this.c = c; }
    public void run(){ s.increment(); }
}

class Counter {
    private int i = 100;
    public synchronized void increment(){ i++; }
    public synchronized int getVal(){ return i; }
}

Thread.sleep(1)これで 120 という望ましい結果が得られるはずだと思いましたが、結果は 115 と 120 の間で変動b.start()しているようです。

それは本当に私を混乱させてきました.私が得られる助けに感謝します, ありがとう

4

5 に答える 5

3

すべてのスレッドが完了した後ではなく、すべてのスレッドを開始した後にカウンターの値を出力しています。

開始したすべてのスレッドで Thread.join() を使用して、完了するまで待機し、値を出力します。または、CountDownLatch を使用します。眠っていると、たまたま正しい結果が得られます。これにより、すべてのスレッドが完了することができますが、それは、実行することが非常に少ないため、1 ミリ秒のスリープで十分です。

于 2013-05-10T20:45:20.917 に答える
1

スレッドが並行して実行されるためです。

c.getVal()1 つ以上の他のスレッドがインクリメントする前に、メイン スレッドで印刷しています。

スリープ中は、他のスレッドが完了してから印刷するのに十分な時間を与えています。

于 2013-05-10T20:45:09.857 に答える
0

スレッドが終了する前に結果を出力している可能性があります (これが結果が異なる理由です)。結果を出力する前に、すべてのスレッドが完了するまで待つ必要があります。

main次のようにメソッドを再構築します。

public static void main(String args[]) {
    Counter c = new Counter();
    MyThread[] a = MyThread[20];
    for (int i = 0; i < 20; i++) {
        a[i] = new MyThread(c);
        a[i].start();
    }
    for (int i = 0; i < 20; i++) {
        a[i].join();        
    }
    System.out.println("The value of the balance is " + c.getVal());
}

まず、2 つのスレッドを作成している間にループが 10 回繰り返されたため、20 回ループしています (したがって、20 スレッドも作成していました)。aすべてのスレッドが完了するまでメインスレッドが待機できるように、(配列を介して) 参照を保持する必要があります( join)。それらがすべて完了すると、正しい結果が返されます。

于 2013-05-12T10:50:22.670 に答える
0

理由:

3 番目の Thread ( を実行するmain()) 関数は、スレッド a と b をランダムな順序で開始した直後に次のステートメントに到達するため、予測できない結果が得られます。

    System.out.println("The value of the balance is " + c.getVal());

次の問題:

b.start() の後に Thread.sleep(1) を追加すると、常に 120 という望ましい結果が得られます。これはなぜですか?

これは、スレッド a と b を終了させるのに十分な時間 (CPU の世界では 1 秒は長い時間です) メイン スレッドを停止したために発生します。

解決策: スレッド a と b の両方が終了するまで、メイン スレッドを待機させます。一方通行:

    Counter c = new Counter();
    for (int i = 0; i < 10; i++) {
        MyThread a = new MyThread(c);
        MyThread b = new MyThread(c);
        a.start();
        b.start();
    }   
    a.join(); // wait for thread a to finish
    b.join(); // wait for thread b to finish

    System.out.println("The value of the balance is " + c.getVal());
于 2013-05-12T04:55:12.640 に答える