public interface ISemaphore extends DistributedObject
Semaphore. Semaphores are often used to restrict the number of
 threads than can access some physical or logical resource.
 
 ISemaphore is a cluster-wide counting semaphore. Conceptually, it maintains
 a set of permits. Each acquire() blocks if necessary until a permit
 is available, and then takes it. Dually, each release() adds a
 permit, potentially releasing a blocking acquirer. However, no actual permit
 objects are used; the semaphore just keeps a count of the number available
 and acts accordingly.
 
 Hazelcast's distributed semaphore implementation guarantees that threads
 invoking any of the acquire methods are selected to
 obtain permits in the order of their invocations (first-in-first-out; FIFO).
 Note that FIFO ordering implies the order which the primary replica of an
 ISemaphore receives these acquire requests. Therefore, it is
 possible for one member to invoke acquire before another member,
 but its request hits the primary replica after the other member.
 
 This class also provides convenience methods, such as
 acquire and release, to work
 with multiple permits at once. Beware of the increased risk of
 indefinite postponement when using the multiple-permit acquire. If permits
 are released one by one, a thread waiting for one permit will acquire
 it before a thread waiting for multiple permits regardless of the call order.
 
Correct usage of a semaphore is established by programming convention in the application.
 As of version 3.12, Hazelcast offers 2 different ISemaphore impls.
 Behaviour of ISemaphore under failure scenarios, including network
 partitions, depends on the impl. The first impl is the one accessed via
 HazelcastInstance.getSemaphore(String). It works on top of
 Hazelcast's async replication algorithm and does not guarantee
 linearizability during failures. During a split-brain scenario, this impl
 loses its atomicity. It is possible for the same ISemaphore instance
 to exist in each side of the network partition and therefore the permit
 counters can diverge. When the cluster heals, Hazelcast will choose one of
 the ISemaphore instances. By default, it is selected from the
 largest partitioned cluster (by number of members). If the cluster sizes are
 all equal, then a random ISemaphore instance will be chosen.
 
ISemaphore impl also supports Quorum QuorumConfig
 in cluster versions 3.10 and higher. However, Hazelcast quorums do not
 guarantee strong consistency under failure scenarios.
 
 The second impl is a new one introduced with the CPSubsystem in
 version 3.12. It is accessed via CPSubsystem.getSemaphore(String).
 It has a major difference to the old implementation, that is, it works on
 top of the Raft consensus algorithm. It offers linearizability during crash
 failures and network partitions. It is CP with respect to the CAP principle.
 If a network partition occurs, it remains available on at most one side of
 the partition.
 
The new CP impl has 2 variations:
CPSubsystem is session-aware. In this
 one, when a caller makes its very first acquire() call, it starts
 a new CP session with the underlying CP group. Then, liveliness of the
 caller is tracked via this CP session. When the caller fails, permits
 acquired by this HazelcastInstance are automatically and safely released.
 However, the session-aware version comes with a limitation, that is,
 a HazelcastInstance cannot release permits before acquiring them
 first. In other words, a HazelcastInstance can release only
 the permits it has acquired earlier. It means, you can acquire a permit
 from one thread and release it from another thread using the same
 HazelcastInstance, but not different instances of HazelcastInstance. This
 behaviour is not compatible with Semaphore.release(). You can use
 the session-aware CP ISemaphore impl by disabling JDK compatibility
 via CPSemaphoreConfig.setJDKCompatible(boolean). Although
 the session-aware impl has a minor difference to the JDK Semaphore, we think
 it is a better fit for distributed environments because of its safe
 auto-cleanup mechanism for acquired permits. Please see
 CPSession for the rationale behind the session mechanism.
 CPSubsystem is sessionless. This impl
 does not perform auto-cleanup of acquired permits on failures. Acquired
 permits are not bound to HazelcastInstance and permits can be released without
 acquiring first. This one is compatible with Semaphore.release().
 However, you need to handle failed permit owners on your own. If a Hazelcast
 server or a client fails while holding some permits, they will not be
 automatically released. You can use the sessionless CP ISemaphore
 impl by enabling JDK compatibility via
 CPSemaphoreConfig.setJDKCompatible(boolean).
 
 There is a subtle difference between the lock and semaphore abstractions.
 A lock can be assigned to at most one endpoint at a time, so we have a total
 order among its holders. However, permits of a semaphore can be assigned to
 multiple endpoints at a time, which implies that we may not have a total
 order among permit holders. In fact, permit holders are partially ordered.
 For this reason, the fencing token approach, which is explained in
 FencedLock, does not work for the semaphore abstraction. Moreover,
 each permit is an independent entity. Multiple permit acquires and reentrant
 lock acquires of a single endpoint are not equivalent. The only case where
 a semaphore behaves like a lock is the binary case, where the semaphore has
 only 1 permit. In this case, the semaphore works like a non-reentrant lock.
 
 All of the API methods in the new CP ISemaphore impl offer
 the exactly-once execution semantics for the session-aware version.
 For instance, even if a release() call is internally retried
 because of a crashed Hazelcast member, the permit is released only once.
 However, this guarantee is not given for the sessionless, a.k.a,
 JDK-compatible CP ISemaphore. For this version, you can tune
 execution semantics via
 CPSubsystemConfig.setFailOnIndeterminateOperationState(boolean).
| Modifier and Type | Method and Description | 
|---|---|
void | 
acquire()
Acquires a permit if one is available, and returns immediately,
 reducing the number of available permits by one. 
 | 
void | 
acquire(int permits)
Acquires the given number of permits if they are available,
 and returns immediately, reducing the number of available permits
 by the given amount. 
 | 
int | 
availablePermits()
Returns the current number of permits currently available in this semaphore. 
 | 
int | 
drainPermits()
Acquires and returns all permits that are available at invocation time. 
 | 
String | 
getName()
Returns the name of this ISemaphore instance. 
 | 
void | 
increasePermits(int increase)
Increases the number of available permits by the indicated amount. 
 | 
boolean | 
init(int permits)
Tries to initialize this ISemaphore instance with the given permit count 
 | 
void | 
reducePermits(int reduction)
Reduces the number of available permits by the indicated amount. 
 | 
void | 
release()
Releases a permit and increases the number of available permits by one. 
 | 
void | 
release(int permits)
Releases the given number of permits and increases the number of
 available permits by that amount. 
 | 
boolean | 
tryAcquire()
Acquires a permit if one is available, and returns  
true
 immediately. | 
boolean | 
tryAcquire(int permits)
Acquires the given number of permits if they are available, and
 returns  
true immediately. | 
boolean | 
tryAcquire(int permits,
          long timeout,
          TimeUnit unit)
Acquires the given number of permits and returns  
true, if they
 become available during the given waiting time. | 
boolean | 
tryAcquire(long timeout,
          TimeUnit unit)
Acquires a permit and returns  
true, if one becomes available
 during the given waiting time and the current thread has not been
 interrupted. | 
destroy, getPartitionKey, getServiceNameString getName()
getName in interface DistributedObjectboolean init(int permits)
permits - the given permit countvoid acquire()
      throws InterruptedException
If no permit is available, then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of three things happens:
release() methods for this
 semaphore and the current thread is next to be assigned a permit,If the current thread:
InterruptedException is thrown and the current thread's
 interrupted status is cleared.InterruptedException - if the current thread is interruptedIllegalStateException - if hazelcast instance is shutdown while waitingvoid acquire(int permits)
      throws InterruptedException
If insufficient permits are available then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of three things happens:
release
 methods for this semaphore, the current thread is next to be assigned
 permits and the number of available permits satisfies this request,InterruptedException is thrown and the current thread's
 interrupted status is cleared.permits - the number of permits to acquireInterruptedException - if the current thread is interruptedIllegalArgumentException - if permits is negative or zeroIllegalStateException - if hazelcast instance is shutdown while waitingint availablePermits()
This method is typically used for debugging and testing purposes.
int drainPermits()
void reducePermits(int reduction)
acquire as it does not block until permits
 become available. Similarly, if the caller has acquired some permits,
 they are not released with this call.reduction - the number of permits to reduceIllegalArgumentException - if reduction is negativevoid increasePermits(int increase)
increase - the number of permits to increaseIllegalArgumentException - if increase is negativevoid release()
 If the underlying ISemaphore impl is the non-JDK compatible
 CP impl that is configured via CPSemaphoreConfig and fetched
 via CPSubsystem, then a HazelcastInstance can only release a permit which
 it has acquired before. In other words, a HazelcastInstance cannot release a permit
 without acquiring it first.
 
 Otherwise, which means the underlying impl is either the JDK compatible
 CP impl configured via CPSemaphoreConfig and fetched
 via CPSubsystem, or it is the old impl fetched via
 HazelcastInstance.getSemaphore(String), there is no requirement
 that a HazelcastInstance that releases a permit must have acquired that permit by
 calling one of the acquire() methods. A HazelcastInstance can freely
 release a permit without acquiring it first. In this case, correct usage
 of a semaphore is established by programming convention in the application.
void release(int permits)
 If the underlying ISemaphore impl is the non-JDK compatible
 CP impl that is configured via CPSemaphoreConfig and fetched
 via CPSubsystem, then a HazelcastInstance can only release a permit which
 it has acquired before. In other words, a HazelcastInstance cannot release a permit
 without acquiring it first.
 
 Otherwise, which means the underlying impl is either the JDK compatible
 CP impl configured via CPSemaphoreConfig and fetched
 via CPSubsystem, or it is the old impl fetched via
 HazelcastInstance.getSemaphore(String), there is no requirement
 that a HazelcastInstance that releases a permit must have acquired that permit by
 calling one of the acquire() methods. A HazelcastInstance can freely
 release a permit without acquiring it first. In this case, correct usage
 of a semaphore is established by programming convention in the application.
permits - the number of permits to releaseIllegalArgumentException - if permits is negativeboolean tryAcquire()
true
 immediately. If no permit is available, returns false
 immediately.true if a permit was acquired, false otherwiseboolean tryAcquire(int permits)
true immediately. If the requested number of permits are
 not available, returns false immediately.permits - the number of permits to acquiretrue if the permits were acquired, false otherwiseIllegalArgumentException - if permits is negativeboolean tryAcquire(long timeout,
                   TimeUnit unit)
            throws InterruptedException
true, if one becomes available
 during the given waiting time and the current thread has not been
 interrupted. If a permit is acquired,
 the number of available permits in the ISemaphore instance is
 also reduced by one.
 If no permit is available, then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of three things happens:
 Returns true if a permit is successfully acquired.
 
 Returns false if the specified waiting time elapses without
 acquiring a permit. If the time is less than or equal to zero,
 the method will not wait at all.
 
If the current thread:
InterruptedException is thrown and the current thread's
 interrupted status is cleared.timeout - the maximum time to wait for a permitunit - the time unit of the timeout argumenttrue if a permit was acquired and false
 if the waiting time elapsed before a permit was acquiredInterruptedException - if the current thread is interruptedIllegalStateException - if hazelcast instance is shutdown while waitingboolean tryAcquire(int permits,
                   long timeout,
                   TimeUnit unit)
            throws InterruptedException
true, if they
 become available during the given waiting time. If permits are acquired,
 the number of available permits in the ISemaphore instance is
 also reduced by the given amount.
 If no sufficient permits are available, then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of three things happens:
true if requested permits are successfully acquired.
 
 Returns false if the specified waiting time elapses without
 acquiring permits. If the time is less than or equal to zero,
 the method will not wait at all.
 
If the current thread:
InterruptedException is thrown and the current thread's
 interrupted status is cleared.permits - the number of permits to acquiretimeout - the maximum time to wait for the permitsunit - the time unit of the timeout argumenttrue if all permits were acquired,
 false if the waiting time elapsed before all permits could be acquiredInterruptedException - if the current thread is interruptedIllegalArgumentException - if permits is negativeIllegalStateException - if hazelcast instance is shutdown while waitingCopyright © 2021 Hazelcast, Inc.. All Rights Reserved.