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

synchronizedとの違いを理解し、ロック制御の本質を押さえよう
目次
ReentrantLock とは?
synchronized の代替として登場したクラスで、より柔軟な排他制御が可能です。
- 明示的に lock() / unlock() で制御できる
- try-finally で確実なロック解放を保証できる
- 公平性の指定、割り込み対応など、高度な制御が可能
synchronized との違い(試験に出やすいポイント)
機能 | synchronized | ReentrantLock |
ロックの取得・解放 | 暗黙的(スコープベース) | 明示的 (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 |