1

このメインは ExecutorService に 1000 ランナブル (テスター) を与え、10 ミリ秒スリープさせてから静的カウンターに 1 を追加するだけです。処刑…どうして?

public class Testit {
    public static void main (String arg[]) {
        int n=1000;
        ExecutorService e1 =  Executors.newFixedThreadPool(20);
        for (int i=0 ;i <n ;i++) {
            e1.execute(new Tester());
        }
        e1.shutdown();
        try {
            e1.awaitTermination(1, TimeUnit.DAYS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Executed "+Tester.tester()+" Tasks.");
    }
}

およびテスター クラス:

public class Tester implements Runnable {
    public static long tester=0;
    @Override
    public void run() {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        finally { tester++; }
    }
    public static long tester() {
        long temp=tester;
        tester=0;
        return temp;
    }
}

編集

によって解決される問題:

finally { synchronized (lock) {tester++;} } 

ありがとうJBニゼット!

4

1 に答える 1

6

カウンターへのアクセスを同期しないため、またlongの書き込みはアトミックではなく、アトミックでも++ないため、カウンターをインクリメントする2つの同時スレッドは、完全に一貫性のない結果、または2ではなく1つのインクリメントのみにつながる可能性があります。

代わりに使用して、これAtomicLongを呼び出します。incrementAndGet()AtomicLong

于 2012-07-26T09:39:18.423 に答える