Как и почему Семафор может выдавать больше разрешений, чем было инициализировано? - PullRequest
10 голосов
/ 26 сентября 2011

Я читаю книгу «Параллелизм Java на практике». В разделе о java.util.concurrent.Semaphore в книге представлены следующие строки. Это комментарий о реализации объектов «виртуального разрешения»

Реализация не имеет объектов фактического разрешения, а Semaphore делает не связывать выданные разрешения с потоками, поэтому разрешение, полученное в один поток может быть освобожден из другого потока. Вы можете думать о acquire как использование разрешения и release как его создание; Semaphore не ограничено количеством разрешений, с которыми оно было создано.

Может кто-нибудь объяснить это? У меня проблемы с пониманием этого. Если мы создаем пул фиксированного размера, мы создаем фиксированное количество «разрешений». Из приведенного выше утверждения похоже, что «разрешения» могут продолжать расти. Почему так устроено?

Ответы [ 6 ]

9 голосов
/ 26 сентября 2011

Вместо того, чтобы «раздавать» объекты разрешений, реализация просто имеет счетчик. Когда новое разрешение «создано», счетчик увеличивается, когда разрешение «возвращается», счетчик уменьшается.

Это обеспечивает гораздо лучшую производительность, чем постоянное создание реальных объектов.

Компромисс заключается в том, что сам семафор не может обнаружить определенные виды программных ошибок (таких как несанкционированный возврат разрешений или утечки семафора). Как кодировщик, вы должны соблюдать правила самостоятельно.

6 голосов
/ 26 сентября 2011

Может кто-нибудь объяснить это? Из приведенного выше утверждения похоже, что «разрешения» могут продолжать расти.

Семафор - счетчик разрешений. приобретение похоже на декремент, который ждет, а не опуститься ниже нуля. У него нет верхнего предела.

Почему он разработан таким образом?

Потому что это просто.

4 голосов
/ 05 июня 2014

Как упоминалось в первом посте " Семафор не ограничен количеством разрешений, которые были созданы с помощью "

Каждый вызов API .release () увеличивает количество разрешений на единицу. Таким образом, у семафоров нет фиксированного размера разрешения

3 голосов
/ 26 сентября 2011

Я думаю, что это означает, сколько раз нам может потребоваться Семафор, как раз, когда мы выпустили «дополнительные» и плюс разрешения, которые он создал.

Например:

Semaphore s = new Semaphore(1); // one permit when initialize

s.acquire();
s.release();

s.release(); // "extra" release.

В данный момент этот семафор допускает одно разрешение изначально и одно «дополнительное» разрешение

0 голосов
/ 12 апреля 2017

Это удивительно для некоторых из нас.

Вы можете легко создать подкласс ограниченного семафора.

/**
 * Terrible performance bounded semaphore.
 **/
 public class BoundedSemaphore extends Semaphore {
    private static final long serialVersionUID = -570124236163243243L;
    final int bound;
    public BoundedSemaphore(int permits) {
        super(permits);
        bound=permits;
    }

    @Override
    synchronized public void acquire() throws InterruptedException {
        super.acquire();
    }

    @Override
    synchronized public boolean tryAcquire() {
        return super.tryAcquire();
    }

    @Override
    synchronized public void release() {
        if( availablePermits()<bound){ 
            super.release();
        }
    }
    @Override
    synchronized public void acquire(int count) throws InterruptedException {
        super.acquire(count);
    }

    @Override
    synchronized public boolean tryAcquire(int count) {
        return super.tryAcquire(count);
    }

    @Override
    synchronized public void release(int count) {
        if( availablePermits()<bound){ 
            super.release(bound-availablePermits());
        }
    }
}
0 голосов
/ 26 сентября 2011

Возможно, последняя строка «Семафор не ограничен количеством разрешений, с которыми он был создан» - это ваш источник путаницы.

Семафор при создании инициализируется с фиксированным набором разрешений. Затем это становится максимальным количеством разрешений, которые семафор может одновременно выдавать в любое время в течение времени жизни этого семафора. Вы не можете динамически увеличивать это число, кроме как путем повторной инициализации семафора.

Значение, если строка в кавычках (из JCIP) такова: во-первых, семантика того, как работает семафор, не ограничивается деталями выдачи и восстановления разрешения - это проявляется в том, что любой поток может иметь доступ к семафору может быть разрешен (даже если этот поток не имел разрешения в первую очередь)

Во-вторых, вы можете динамически уменьшить максимальное количество разрешений семафора - вызвав метод reducePermits(int).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...