1
package demo5;

class Process extends Thread {

static int counter = 0;

public static  synchronized void increment() { counter++; }

public void run() {
    for (int i = 0; i < 1000000; i++)
    {
        increment();
    }
    System.out.println("Done.");
  }
}

public class App {

public static void main(String[] args) throws InterruptedException {
    Process p1 = new Process();
    Process p2 = new Process();
    p1.start();
    p2.start();

    p1.join();
    p2.join();

    System.out.println("Value of count is :" + p1.counter);

}

}

インクリメント関数を非静的関数として宣言すると、最後のカウンターの値は 200 万にはなりません。

一方、increment メソッドが static として定義されている場合は適切に機能します。

私の知る限り、すべての Process オブジェクトに対してインクリメント関数は 1 つしかありません..では、なぜそれを静的メソッドとして宣言する必要があるのでしょうか..?

ありがとう

4

2 に答える 2

7

static と宣言するとsynchronized、 Process.class インスタンスがロックされます。したがって、実行中のすべてのスレッドは、incrementメソッド内のオブジェクトでブロックされます。静的を削除すると、各スレッドは Thread インスタンス (この場合は 2 つ) でのみブロックされます。

その結果、counter変数は並行してインクリメントされ、何度も指摘されているように、int のインクリメントはスレッドセーフではありません。

As far as I know there will be only ONE increment function for all the Process objects

Process クラスにはインクリメント関数が 1 つありますが、同期はメソッドではなくオブジェクトに対して行われます。

class Process{
     public synchronized void increment() { counter++; }
}

以下と同等です:

class Process{
     public void increment() { 
           synchronized(this){
                  counter++; 
            }
}

編集: Roukiの質問に答える。

class Process{
     public static synchronized void increment() { counter++; }
}

に相当する

class Process{
     public void increment() { 
           synchronized(Process.class){
                  counter++; 
            }
}
于 2013-04-09T14:46:11.733 に答える