注目記事

【Javaコード入門】スレッド_④AtomicXxxxxクラス

ロックフリーな同期処理を実装する – AtomicXxxxxクラス

java.util.concurrent.atomicパッケージでは、値の代入/取得といった処理をハードウェアレベルでアトミックに実行する手段を提供します。

  • AtomicBoolean
  • AtomicInteger
  • AtomicIntegerArray
  • AtomicLong
  • AtomicLongArray

これらのクラスを利用することで、synchronized修飾子、ReentrantLockクラスのようにロックを取得することなく、処理を同期させることが可能になります。
それぞれのクラスで利用できる処理には、以下のようなものがあります。

AtomicXxxxxクラスの主なメソッド(*はAtomicBooleanでは利用できないもの)
メソッド 概要
get() 現在の値を取得
getAndSet(newValue) 現在の値を取得し、指定された値を設定
set(newValue) 指定された値を設定
*getAndAdd(delta) 指定された値を追加(操作前の値を取得)
*addAndGet(delta) 指定された値を追加(操作後の値を取得)
*getAndDecrement() 現在の値を1デクリメント(操作前の値を取得)
*decrementAndGet() 現在の値を1デクリメント(操作後の値を取得)
*getAndIncrement() 現在の値を1インクリメント(操作前の値を取得)
*incrementAndGet() 現在の値を1インクリメント(操作後の値を取得)

以下は、synchronized修飾子の項のサンプル(incrementメソッド)をAtomicIntegerクラスで書き換えたものです。標準的な「i++」演算はアトミックではありませんが、AtomicInteger#getAndIncrementメソッドはアトミックなので、値の取得からインクリメント、再代入の過程に他のスレッドが割り込むことはありません。

AtomicSample.java
  1. package com.example.mynavi.thread;
  2.  
  3. import java.util.concurrent.atomic.AtomicInteger;
  4.  
  5. public class AtomicSample {
  6.   private AtomicInteger count = new AtomicInteger();
  7.  
  8.   public static void main(String[] args) {
  9.     var as = new AtomicSample();
  10.     as.execute();
  11.   }
  12.  
  13.   public void execute() {
  14.     final int THREAD_MAX = 300000;
  15.     var ts = new Thread[THREAD_MAX];
  16.     for (var i = 0; i < THREAD_MAX; i++) {
  17.       ts[i] = new Thread(new MyThread(this));
  18.       ts[i].start();
  19.     }
  20.     for (var i = 0; i < THREAD_MAX; i++) {
  21.       try {
  22.         ts[i].join();
  23.       } catch (InterruptedException e) {
  24.         System.out.println(e);
  25.       }
  26.     }
  27.     System.out.println(count);
  28.   }
  29.  
  30.   public void increment() {
  31.     count.getAndIncrement();
  32.   }
  33.  
  34.   private static class MyThread implements Runnable {
  35.     private AtomicSample _counter;
  36.  
  37.     public MyThread(AtomicSample counter) {
  38.       this._counter = counter;
  39.     }
  40.  
  41.     @Override
  42.     public void run() {
  43.       _counter.increment();
  44.     }
  45.   }
  46. }
スレッド_目次
Threadクラス/Runnableインターフェイス
synchronized修飾子/ブロック
ReentrantLockクラス
AtomicXxxxxクラス
Executorsクラス

監修

山田祥寛(有限会社 WINGSプロジェクト)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NEC にてシステム企画業務に携わるが、2003年 4 月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト(https://wings.msn.to/)」の代表でもある。主な著書に『改訂 3 版JavaScript 本格入門』(技術評論社)、「独習シリーズ(C#・Python・PHP・Ruby・JSP&サーブレットなど)」(翔泳社)、「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravel など)」(Amazon Kindle)など。売り上げの累計は100万部を超える。