Concurrency
synchronized: 同じスレッドは同じmonitorへ再入できる
synchronizedメソッドが同じオブジェクトの別のsynchronizedメソッドを呼んでも、同じスレッドなら停止しません。
SourceReentrantMonitors.java
Java 21
package examples.synchronization;
public final class ReentrantMonitors {
private int calls;
public synchronized int outer() {
return inner();
}
private synchronized int inner() {
return ++calls;
}
}TestReentrantMonitorsTest.java
Java 21
package examples.synchronization;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
class ReentrantMonitorsTest {
@Test
void 同じスレッドは保持中のsynchronizedモニタを再入できる() {
var monitor = new ReentrantMonitors();
assertEquals(1, monitor.outer());
assertEquals(2, monitor.outer());
}
}01Assertion
このテストで確認できること
- synchronizedのouterから同じinstanceのsynchronized innerを呼ぶ
- 同じスレッドはmonitorを再入して状態を更新できる
Javaのintrinsic lockは再入可能です。ただし再入可能でもロック範囲が広い設計は競合や待ち時間を増やすため、共有状態を小さく保ちます。
OBSERVED RESULT
expected: outer calls → 1, 2
actual: 1, 2