第6章 並行処理の機能強化 : 問題 3 : AtomicLong と LongAdder
問題
1,000個のスレッドを生成し、各スレッドは、ある一つのカウンターを100,000回インクリメントする
AtomicLong と LongAdder を使用した場合の性能を比較せよ
解答
■ AtomicLong
final int TASK = 1000; final int COUNT = 100_000; AtomicLong globalCounter = new AtomicLong(0); CountDownLatch latch = new CountDownLatch(TASK); ExecutorService pool = Executors.newCachedThreadPool(); long startTime = System.nanoTime(); for (int n = 0; n < TASK; n++) { pool.submit( () -> { for (int i = 0; i < COUNT; i++) { globalCounter.incrementAndGet(); } latch.countDown(); } ); } pool.shutdown(); latch.await(); System.out.println("経過時間 : " + (System.nanoTime() - startTime)/1E9 + "秒"); System.out.println("カウンタ : " + globalCounter);
■ LongAdder
final int TASK = 1000; final int COUNT = 100_000; LongAdder globalCounter = new LongAdder(); CountDownLatch latch = new CountDownLatch(TASK); ExecutorService pool = Executors.newCachedThreadPool(); long startTime = System.nanoTime(); for (int n = 0; n < TASK; n++) { pool.submit( () -> { for (int i = 0; i < COUNT; i++) { globalCounter.increment(); } latch.countDown(); } ); } pool.shutdown(); latch.await(); System.out.println("経過時間 : " + (System.nanoTime() - startTime)/1E9 + "秒"); System.out.println("カウンタ : " + globalCounter);
所要時間は、私のマシン環境で
AtomicLong
: 2.044秒
LongAdder
: 0.610秒
となり、約4倍の差でした