[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 12428] SharedCounter の実験 (1)



高橋(徹)です。

複数のスレッドから変数(int)を更新する実験プログラムを作りました。
  添付のSharedCounterIncrementor.java

インスタンスフィールド int counterを2つのスレッドでインクリメントします。
また、各スレッドではローカル変数にインクリメントした回数を記録します。
共有アクセスされるcounterの最終値と、各スレッドが記録したインクリメント
回数との違いをみれば、共有アクセスされるcounterでのスレッド間の競合が
判ります。

2つのマシンでの実行結果は下記のとおりです。
(1) シングルCPU(AMD Athlon XP), Windows XP, J2SE 5.0 Update7
   I have incremented 66704210 times
   I have incremented 65625349 times
   Shared counter = 131083161

  カウンタの最終値は131,083,161ですが、各スレッドのインクリメント回数の
 合計 132,329,559に対して1%ほど小さな値となっています。100回に1回の頻度
 で競合が発生しているものと思われます。

(2) デュアルコアCPU(AMD Athlon 64x2), Windows XP, J2SE 5.0 Update7
   I have incremented 48362964 times
   I have incremented 48129724 times
   Shared counter = 48497262

 カウンタの最終値は48,497,262ですが、各スレッドのインクリメント回数
 合計96,492,688に対して50%も小さな値となっています。2回に1回の頻度で
 競合が発生しているものと思われます。


--
TAKAHASHI,Toru
torutk@xxxxxxxxxxxx

public class SharedCounterIncrementor implements Runnable {
    private int counter;

    public void run() {
        int numIncremented = 0;
        while (true) {
            counter++;
            numIncremented++;
            if (Thread.currentThread().isInterrupted()) {
                System.out.printf("I have incremented %d times%n",
                                  numIncremented);
                return;
            }
        }
    }

    public final static void main(final String[] args) throws Exception {
        SharedCounterIncrementor sci = new SharedCounterIncrementor();
        Thread t1 = new Thread(sci);
        Thread t2 = new Thread(sci);
        t1.start();
        t2.start();
        Thread.sleep(10000);
        t1.interrupt();
        t2.interrupt();
        t1.join();
        t2.join();
        System.out.println("Shared counter is " + sci.counter);
    }
}