Java Gold SE11対策:ReentrantLock の詳細と使い方

アイキャッチ画像

synchronizedとの違いを理解し、ロック制御の本質を押さえよう

ReentrantLock とは?

synchronized の代替として登場したクラスで、より柔軟な排他制御が可能です。

  • 明示的に lock() / unlock() で制御できる
  • try-finally で確実なロック解放を保証できる
  • 公平性の指定、割り込み対応など、高度な制御が可能

synchronized との違い(試験に出やすいポイント)

機能synchronizedReentrantLock
ロックの取得・解放暗黙的(スコープベース)明示的 (lock() / unlock())
ロックの再入(再帰)○(Reentrant = 再入可能)
finally での解除保証×(構文で完結)○(finally必須)
公平性の制御×○(new ReentrantLock(true))
割り込み対応×○(ただし試験範囲外)

基本の使い方(unlockはfinallyで!)

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockExample {

    private final ReentrantLock lock = new ReentrantLock();

    private int count = 0;

    public void increment() {

        lock.lock(); // 🔒 ロック開始

        try {

            count++;

        } finally {

            lock.unlock(); // 🔓 ロック解除(finallyで確実に)

        }

    }

}

💥 試験では「unlock を finally に書いていないコードを見抜けるか?」がよく出題されます!

公平性の設定

ReentrantLock fairLock = new ReentrantLock(true);

  • false(デフォルト):非公平(高速)
  • true:スレッドの待ち順を守る公平ロック(FIFO)

実務では重要ですが、試験ではコードの動作理解が中心です。

割り込み対応は試験 対象外

lock.lockInterruptibly();

lock.tryLock(1, TimeUnit.SECONDS);

これらは実務で非常に有用ですが、Java Gold SE11 の試験では出題対象外です。
→ 試験対策としては覚える優先度を下げてOK。

Reentrant = 再入可能

lock.lock();

lock.lock(); // 同じスレッドならOK(再入)

lock.unlock();

lock.unlock(); // 呼んだ回数だけ unlock() が必要

synchronized も同様に 再入可能 です。
この性質は 共通 しているので、両者で混乱しないようにしましょう。

🔄 Object型のロックとの比較・使い分け

synchronized を使う際に、以下のように Object 型のロックを明示的に定義して使う書き方があります:

private final Object lock = new Object();

public void doSomething() {

    synchronized (lock) {

        // 排他処理

    }

}

これはReentrantLockと非常に用途が近く、両者とも「特定の対象に対してロックをかける」ことができるという点で共通しています。

ReentrantLockとの比較表

比較項目synchronized(Object)ReentrantLock
構文の簡潔さ◎ 簡単△ 手動で lock/unlock 必要
finally での unlock不要(スコープ終了で自動)必須(忘れるとデッドロックの原因)
タイムアウト付きロック❌ なし✅ tryLock(timeout) あり
割り込み可能なロック❌ 不可✅ lockInterruptibly() あり
再入可能性✅(同一スレッドならOK)✅(Reentrant 特性)
複数ロック制御の柔軟性△ 管理しにくい◎ ロックをオブジェクトとして扱える

✅ どう使い分けるべきか?

目的・場面推奨ロック方式
シンプルな排他制御を行いたいsynchronized(Objectロック含む)
ロック取得にタイムアウトや割り込み対応が必要ReentrantLock
ロックを変数で動的に管理したいReentrantLock
unlock 書き忘れを避けたいsynchronized(構文安全)

まとめ(試験対策用)

項目ポイント
lock() / unlock()明示的に記述。finally で確実に unlock() を行うこと
再入可能同じスレッドなら複数回 lock() 可。unlock() も回数分必要
公平性new ReentrantLock(true) で FIFO に処理させることが可能
割り込み対応実務では重要だが、Java Gold SE11では試験対象外
Object型のロックsynchronized(lockObj) で排他制御するのも試験に出る
使い分けの理解シンプルな用途は synchronized、柔軟さが欲しい場合は ReentrantLock