Разница между семафором, инициализированным с 1 и 0
пожалуйста, скажите, что такое семафор разницы, инициализированный с 1 и нулем. как показано ниже:
public static Semaphore semOne = new Semaphore(1);
и
public static Semaphore semZero = new Semaphore(0);
3 ответов
аргументом для экземпляра семафора является количество доступных "разрешений". Это может быть любое целое число, а не только 0 или 1.
на semZero
все acquire()
вызовы будут блокировать и tryAcquire()
вызовы вернут false, пока вы не сделаете release()
на semOne
первый acquire()
вызовы будут успешными, а остальные будут блокироваться до первого выпуска.
класс хорошо документирован здесь.
параметры: разрешения-начальное количество доступных разрешений. Этот значение может быть отрицательным, и в этом случае релизы должны произойти до приобретение будет предоставлено.
конструктор параметр permits
(начальный счетчик семафоров) - это количество вызовов Semaphore.aquire()
Это можно сделать до того, как счетчик (разрешения) равен нулю, а acquire()
блоки.
1 является нормальным значением, чтобы гарантировать, что только один поток проходит приобретение.
semaphore.acquire();
try {
// Critical region
...
} finally {
semaphore.release();
}
для использования 0 посмотреть здесь.
семафор - это низкоуровневый механизм параллелизма: счетчик при достижении нуля блокирование выполнения потока. Это происходит от Дейкстра где двоичный семафор (0, 1) является метафорой для железнодорожного семафора, говорящего pass (остановка, когда 0, pass --permits) и в конце защищенного пути делает выпуск (++permits).
когда я впервые прочитал документацию семафора, я также неправильно истолковал объяснение. Главное, что я пропустил, - это часть "...Начальное количество разрешений...'. Как-то я думал, что это будет количество разрешений, которые будут доступны как максимум, но это не так. В конце концов семафор просто подсчитывает от любого числа, но только запускает потоки enable waiting (которые используют acquire), когда разрешения семафора выше 1.
простая часть (не threading) код показывает это тоже:
@Test
public void testNegativeSemaphore()
{
Semaphore semaphore = new Semaphore(-2);
assertEquals(-2, semaphore.availablePermits());
semaphore.release();
assertEquals(-1, semaphore.availablePermits());
semaphore.release();
assertEquals(0, semaphore.availablePermits());
semaphore.release();
assertEquals(1, semaphore.availablePermits());
}
Как показывает код, доступные разрешения увеличиваются при каждом выпуске, только чтобы позволить другим потокам получить разрешение, как только значение достигнет 1 или выше.
обратите внимание, что оттуда availablePermits не может стать отрицательным с помощью aqcuire, потому что, если есть 0 разрешений, весь смысл семафора-ждать разрешения, чтобы стать доступным снова!