ロックフリーな同期処理を実装する – 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
- package com.example.mynavi.thread;
- import java.util.concurrent.atomic.AtomicInteger;
- public class AtomicSample {
- private AtomicInteger count = new AtomicInteger();
- public static void main(String[] args) {
- var as = new AtomicSample();
- as.execute();
- }
- public void execute() {
- final int THREAD_MAX = 300000;
- var ts = new Thread[THREAD_MAX];
- for (var i = 0; i < THREAD_MAX; i++) {
- ts[i] = new Thread(new MyThread(this));
- ts[i].start();
- }
- for (var i = 0; i < THREAD_MAX; i++) {
- try {
- ts[i].join();
- } catch (InterruptedException e) {
- System.out.println(e);
- }
- }
- System.out.println(count);
- }
- public void increment() {
- count.getAndIncrement();
- }
- private static class MyThread implements Runnable {
- private AtomicSample _counter;
- public MyThread(AtomicSample counter) {
- this._counter = counter;
- }
- @Override
- public void run() {
- _counter.increment();
- }
- }
- }
- スレッド_目次
- 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万部を超える。