// Not really how java.util.concurrent.Semaphore is implemented
@ThreadSafe
public class SemaphoreOnLock {
private final Lock lock = new ReentrantLock();
// CONDITION PREDICATE: permitsAvailable (permits > 0)
private final Condition permitsAvailable = lock.newCondition();
@GuardedBy("lock") private int permits;
SemaphoreOnLock(int initialPermits) {
lock.lock();
try {
permits = initialPermits;
} finally {
lock.unlock();
}
}
/* other code omitted.... */
У меня есть вопрос о примере выше, который извлекается из Java Concurrency в Практике. Листинг 14.12. Считывание семафора с использованием блокировки.
Мне интересно, почему нам нужно получить блокировку в конструкторе (как показано, вызывается lock.lock()). Насколько я знаю, конструктор является атомарным (кроме ссылки экранированным), поскольку ни один другой поток не может получить ссылку, следовательно, полуконструированный объект не будет виден другим потокам. Поэтому для конструкторов нам не нужен синхронный модификатор. Кроме того, нам не нужно беспокоиться о видимости памяти, если объект безопасно опубликован.
Итак, зачем нам нужен объект ReentrantLock внутри конструктора?