Spec-Zone .ru
спецификации, руководства, описания, API
|
public class Semaphore extends Object implements Serializable
acquire()
блоки в случае необходимости до разрешения доступны, и затем берут это. Каждый release()
добавляет разрешение, потенциально выпуская получателя блокирования. Однако, никакие фактические объекты разрешения не используются; Semaphore
только проводит подсчет доступного числа и действует соответственно. Семафоры часто используются, чтобы ограничить число потоков, чем может получить доступ к некоторым (физический или логичный) ресурс. Например, вот class, который использует семафор, чтобы управлять доступом к пулу элементов:
class Pool {
private static final int MAX_AVAILABLE = 100;
private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
public Object getItem() throws InterruptedException {
available.acquire();
return getNextAvailableItem();
}
public void putItem(Object x) {
if (markAsUnused(x))
available.release();
}
// Not a particularly efficient data structure; just for demo
protected Object[] items = ... whatever kinds of items being managed
protected boolean[] used = new boolean[MAX_AVAILABLE];
protected synchronized Object getNextAvailableItem() {
for (int i = 0; i < MAX_AVAILABLE; ++i) {
if (!used[i]) {
used[i] = true;
return items[i];
}
}
return null; // not reached
}
protected synchronized boolean markAsUnused(Object item) {
for (int i = 0; i < MAX_AVAILABLE; ++i) {
if (item == items[i]) {
if (used[i]) {
used[i] = false;
return true;
} else
return false;
}
}
return false;
}
}
Прежде, чем получить элемент каждый поток должен получить разрешение от семафора, гарантируя, что элемент доступен для использования. Когда поток закончился с элементом, это возвращается назад к пулу, и разрешение возвращается к семафору, позволяя другой поток получить тот элемент. Отметьте, что никакая блокировка синхронизации не сохранена когда acquire()
вызывается, поскольку это препятствовало бы тому, чтобы элемент был возвращен к пулу. Семафор инкапсулирует синхронизацию, должен был ограничить доступ к пулу, отдельно от любой синхронизации должен был поддержать непротиворечивость пула непосредственно.
У семафора, инициализированного одному, и который используется так, что это только, есть самое большее одно доступное разрешение, может служить блокировкой взаимного исключения. Это более обычно известно как двоичный семафор, потому что у него только есть два состояния: одно разрешение доступные, или нулевые доступные разрешения. Когда использующийся таким образом, у двоичного семафора есть свойство (в отличие от многих Lock
реализации), что "блокировка" может быть выпущена потоком кроме владельца (поскольку у семафоров нет никакого понятия владения). Это может быть полезно в некоторых специализированных контекстах, таково как восстановление мертвой блокировки.
Конструктор для этого class дополнительно принимает параметр справедливости. Когда ложь набора, этот class не делает гарантий о порядке, в котором потоки получают разрешения. В частности неуклюжая походка разрешается, то есть, вызов потока acquire()
может быть выделен разрешение перед потоком, который ожидал - логически, новый поток занимает место во главе очереди потоков ожидания. Когда справедливость будет установлена истина, семафор гарантирует что потоки, вызывающие любой из acquire
методы выбираются, чтобы получить разрешения в порядке, в котором был обработан их вызов тех методов (первым прибыл - первым убыл; FIFO). Отметьте, что FIFO, упорядочивающий обязательно, применяется к определенным внутренним точкам выполнения в пределах этих методов. Так, для одного потока возможно вызвать acquire
перед другим, но достигают точки упорядочивания после другого, и так же по возврату из метода. Также отметьте что несинхронизированное tryAcquire
методы не соблюдают установку справедливости, но возьмут любые разрешения, которые доступны.
Обычно, семафоры, используемые, чтобы управлять доступом ресурса, должны быть инициализированы как ярмарка, чтобы гарантировать, что никакой поток не исчерпан ресурсы из доступа к ресурсу. При использовании семафоров для других видов управления синхронизацией преимущества пропускной способности несправедливого упорядочивания часто перевешивают соображения справедливости.
Этот class также обеспечивает методы удобства для acquire
и release
многократные разрешения за один раз. Остерегайтесь увеличенного риска неопределенной отсрочки, когда эти методы используются без истины набора справедливости.
Эффекты непротиворечивости памяти: Действия в потоке до вызова метода "выпуска" такой как release()
произойдите - прежде, чем действия после успешного "получат" метод такой как acquire()
в другом потоке.
Конструктор и Описание |
---|
Semaphore(int permits)
Создает a
Semaphore с данным числом разрешений и несправедливой установки справедливости. |
Semaphore(int permits, boolean fair)
Создает a
Semaphore с данным числом разрешений и данной установки справедливости. |
Модификатор и Тип | Метод и Описание |
---|---|
void |
acquire()
Получает разрешение от этого семафора, блокируя, пока каждый не доступен, или поток прерывается.
|
void |
acquire(int permits)
Получает данное число разрешений от этого семафора, блокируя, пока все не доступны, или поток прерывается.
|
void |
acquireUninterruptibly()
Получает разрешение от этого семафора, блокируя, пока каждый не доступен.
|
void |
acquireUninterruptibly(int permits)
Получает данное число разрешений от этого семафора, блокируя, пока все не доступны.
|
int |
availablePermits()
Возвращает текущее число разрешений, доступных в этом семафоре.
|
int |
drainPermits()
Получает и возвращает все разрешения, которые сразу доступны.
|
protected Collection<Thread> |
getQueuedThreads()
Возвращает набор, содержащий потоки, которые могут ожидать, чтобы получить.
|
int |
getQueueLength()
Возвращает оценку числа потоков, ожидающих, чтобы получить.
|
boolean |
hasQueuedThreads()
Запросы, ожидают ли какие-либо потоки, чтобы получить.
|
boolean |
isFair()
Возвраты
true если у этого семафора есть истина набора справедливости. |
protected void |
reducePermits(int reduction)
Уменьшает число доступных разрешений обозначенным сокращением.
|
void |
release()
Выпускает разрешение, возвращая это семафору.
|
void |
release(int permits)
Выпускает данное число разрешений, возвращая их семафору.
|
Строка |
toString()
Возвращает строку, идентифицирующую этот семафор, так же как его состояние.
|
boolean |
tryAcquire()
Получает разрешение от этого семафора, только если каждый доступен во время вызова.
|
boolean |
tryAcquire(int permits)
Получает данное число разрешений от этого семафора, только если все доступны во время вызова.
|
boolean |
tryAcquire(int permits, long timeout, TimeUnit unit)
Получает данное число разрешений от этого семафора, если все становятся доступными в пределах данного времени ожидания, и текущий поток не был прерван.
|
boolean |
tryAcquire(long timeout, TimeUnit unit)
Получает разрешение от этого семафора, если Вы становитесь доступными в пределах данного времени ожидания, и текущий поток не был прерван.
|
public Semaphore(int permits)
Semaphore
с данным числом разрешений и несправедливой установки справедливости.permits
- начальное число доступных разрешений. Это значение может быть отрицательным, когда выпуски должны произойти прежде, чем любой получает, будет предоставлен.public Semaphore(int permits, boolean fair)
Semaphore
с данным числом разрешений и данной установки справедливости.permits
- начальное число доступных разрешений. Это значение может быть отрицательным, когда выпуски должны произойти прежде, чем любой получает, будет предоставлен.fair
- true
если этот семафор гарантирует сначала - в первом предоставлении разрешений в соответствии с конкуренцией, еще false
public void acquire() throws InterruptedException
Получает разрешение, если Вы доступны и сразу возвращаетесь, сокращая количество доступных разрешений одним.
Если никакое разрешение не доступно тогда, текущий поток становится отключенным в целях планирования потоков и бездействует, пока одна из двух вещей не происходит:
release()
метод для этого семафора и текущего потока рядом с быть присвоенным разрешение; или Если текущий поток:
InterruptedException
бросается и прерванное состояние текущего потока очищается.InterruptedException
- если текущий поток прерываетсяpublic void acquireUninterruptibly()
Получает разрешение, если Вы доступны и сразу возвращаетесь, сокращая количество доступных разрешений одним.
Если никакое разрешение не доступно тогда, текущий поток становится отключенным в целях планирования потоков и бездействует, пока некоторый другой поток не вызывает release()
метод для этого семафора и текущего потока рядом с быть присвоенным разрешение.
Если текущий поток будет прерван, ожидая разрешения тогда, то он будет продолжать ожидать, но время, в которое присваивается поток, разрешение может измениться по сравнению со временем, он получил бы разрешение, не имел никакого произошедшего прерывания. Когда поток действительно возвратится из этого метода, его состояние прерывания будет установлено.
public boolean tryAcquire()
Получает разрешение, если Вы доступны и сразу возвращаетесь со значением true
, сокращение количества доступных разрешений одним.
Если никакое разрешение не будет доступно тогда, то этот метод сразу возвратится со значением false
.
Даже когда этот семафор был установлен использовать справедливую политику упорядочивания, звонок tryAcquire()
сразу получит разрешение, если Вы будете доступны, ожидают ли другие потоки в настоящий момент. Это поведение "неуклюжей походки" может быть полезным при определенных обстоятельствах, даже при том, что оно повреждает справедливость. Если Вы хотите соблюдать установку справедливости, то используйте tryAcquire(0, TimeUnit.SECONDS)
который почти эквивалентен (это также обнаруживает прерывание).
true
если разрешение было получено и false
иначеpublic boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException
Получает разрешение, если Вы доступны и сразу возвращаетесь со значением true
, сокращение количества доступных разрешений одним.
Если никакое разрешение не доступно тогда, текущий поток становится отключенным в целях планирования потоков и бездействует, пока одна из трех вещей не происходит:
release()
метод для этого семафора и текущего потока рядом с быть присвоенным разрешение; или Если разрешение получается тогда значение true
возвращается.
Если текущий поток:
InterruptedException
бросается и прерванное состояние текущего потока очищается. Если указанное время ожидания протекает тогда значение false
возвращается. Если время будет меньше чем или равно нулю, то метод не будет ожидать вообще.
timeout
- максимальное время, чтобы ожидать разрешенияunit
- единица измерения времени timeout
параметрtrue
если разрешение было получено и false
если время ожидания, законченное перед разрешением, было полученоInterruptedException
- если текущий поток прерываетсяpublic void release()
Выпускает разрешение, увеличивая число доступных разрешений одним. Если какие-либо потоки пытаются получить разрешение, то каждый выбирается и дается разрешение, которое было только выпущено. Тот поток (ре), включенное в целях планирования потоков.
Нет никакого требования, чтобы поток, который выпускает разрешение, получил то разрешение, вызывая acquire()
. Корректное использование семафора устанавливается, программируя соглашение в приложении.
public void acquire(int permits) throws InterruptedException
Получает данное число разрешений, если они доступны, и сразу возвращается, сокращая количество доступных разрешений данным количеством.
Если недостаточные разрешения доступны тогда, текущий поток становится отключенным в целях планирования потоков и бездействует, пока одна из двух вещей не происходит:
release
методы для этого семафора, текущий поток рядом с быть присвоенным, разрешения и число доступных разрешений удовлетворяют этот запрос; или Если текущий поток:
InterruptedException
бросается и прерванное состояние текущего потока очищается. Любые разрешения, которые должны были быть присвоены этому потоку, вместо этого присваиваются другим потокам, пытающимся получать разрешения, как будто разрешения были сделаны доступными звонком release()
.permits
- число разрешений, чтобы получитьInterruptedException
- если текущий поток прерываетсяIllegalArgumentException
- если permits
отрицательноpublic void acquireUninterruptibly(int permits)
Получает данное число разрешений, если они доступны, и сразу возвращается, сокращая количество доступных разрешений данным количеством.
Если недостаточные разрешения доступны тогда, текущий поток становится отключенным в целях планирования потоков и бездействует, пока некоторый другой поток не вызывает один из release
методы для этого семафора, текущий поток рядом с быть присвоенным, разрешения и число доступных разрешений удовлетворяют этот запрос.
Если текущий поток будет прерван, ожидая разрешений тогда, то он будет продолжать ожидать, и на его позицию в очереди не влияют. Когда поток действительно возвратится из этого метода, его состояние прерывания будет установлено.
permits
- число разрешений, чтобы получитьIllegalArgumentException
- если permits
отрицательноpublic boolean tryAcquire(int permits)
Получает данное число разрешений, если они доступны, и сразу возвращается, со значением true
, сокращение количества доступных разрешений данным количеством.
Если недостаточные разрешения будут доступны тогда, то этот метод сразу возвратится со значением false
и число доступных разрешений неизменно.
Даже когда этот семафор был установлен использовать справедливую политику упорядочивания, звонок tryAcquire
сразу получит разрешение, если Вы будете доступны, ожидают ли другие потоки в настоящий момент. Это поведение "неуклюжей походки" может быть полезным при определенных обстоятельствах, даже при том, что оно повреждает справедливость. Если Вы хотите соблюдать установку справедливости, то используйте tryAcquire(permits, 0, TimeUnit.SECONDS)
который почти эквивалентен (это также обнаруживает прерывание).
permits
- число разрешений, чтобы получитьtrue
если разрешения были получены и false
иначеIllegalArgumentException
- если permits
отрицательноpublic boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException
Получает данное число разрешений, если они доступны, и сразу возвращается, со значением true
, сокращение количества доступных разрешений данным количеством.
Если недостаточные разрешения доступны тогда, текущий поток становится отключенным в целях планирования потоков и бездействует, пока одна из трех вещей не происходит:
release
методы для этого семафора, текущий поток рядом с быть присвоенным, разрешения и число доступных разрешений удовлетворяют этот запрос; или Если разрешения получаются тогда значение true
возвращается.
Если текущий поток:
InterruptedException
бросается и прерванное состояние текущего потока очищается. Любые разрешения, которые должны были быть присвоены этому потоку, вместо этого присваиваются другим потокам, пытающимся получать разрешения, как будто разрешения были сделаны доступными звонком release()
. Если указанное время ожидания протекает тогда значение false
возвращается. Если время будет меньше чем или равно нулю, то метод не будет ожидать вообще. Любые разрешения, которые должны были быть присвоены этому потоку, вместо этого присваиваются другим потокам, пытающимся получать разрешения, как будто разрешения были сделаны доступными звонком release()
.
permits
- число разрешений, чтобы получитьtimeout
- максимальное время, чтобы ожидать разрешенийunit
- единица измерения времени timeout
параметрtrue
если все разрешения были получены и false
если время ожидания, законченное перед всеми разрешениями, было полученоInterruptedException
- если текущий поток прерываетсяIllegalArgumentException
- если permits
отрицательноpublic void release(int permits)
Выпускает данное число разрешений, увеличивая число доступных разрешений тем количеством. Если какие-либо потоки пытаются получить разрешения, то каждый выбирается и дается разрешения, которые были только выпущены. Если число доступных разрешений удовлетворяет запрос того потока тогда, что поток (ре), включенное в целях планирования потоков; иначе поток будет ожидать, пока достаточные разрешения не доступны. Если есть все еще разрешения, доступные после того, как запрос этого потока был удовлетворен, то те разрешения присваиваются поочередно другим потокам, пытающимся получать разрешения.
Нет никакого требования, чтобы поток, который выпускает разрешение, получил то разрешение, вызывая acquire
. Корректное использование семафора устанавливается, программируя соглашение в приложении.
permits
- число разрешений, чтобы выпуститьIllegalArgumentException
- если permits
отрицательноpublic int availablePermits()
Этот метод обычно используется для отладки и тестирования целей.
public int drainPermits()
protected void reducePermits(int reduction)
acquire
в этом это не блокирует ожидание разрешений, чтобы стать доступным.reduction
- число разрешений, чтобы удалитьIllegalArgumentException
- если reduction
отрицательноpublic boolean isFair()
true
если у этого семафора есть истина набора справедливости.true
если у этого семафора есть истина набора справедливостиpublic final boolean hasQueuedThreads()
true
возврат не гарантирует, что любой другой поток будет когда-либо получать. Этот метод разрабатывается прежде всего для использования в контроле системного состояния.true
если могут быть другие потоки, ожидающие, чтобы получить блокировкуpublic final int getQueueLength()
protected Collection<Thread> getQueuedThreads()
public String toString()
"Permits ="
сопровождаемый числом разрешений.
Для дальнейшей ссылки API и документации разработчика, см. Java Документация SE. Та документация содержит более подробные, предназначенные разработчиком описания, с концептуальными краткими обзорами, определениями сроков, обходных решений, и рабочих примеров кода.
Авторское право © 1993, 2013, Oracle и/или его филиалы. Все права защищены.
Проект сборка-b92