com.hazelcast.core.ISemaphore Maven / Gradle / Ivy
/*
* Copyright (c) 2008-2017, Hazelcast, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hazelcast.core;
import java.util.concurrent.TimeUnit;
/**
* ISemaphore is a backed-up distributed alternative to the {@link java.util.concurrent.Semaphore}.
*
* ISemaphore is a cluster-wide counting semaphore. Conceptually,
* it maintains a set of permits. Each {@link #acquire()} blocks if necessary until
* a permit is available, and then takes it. Each {@link #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.
* The Hazelcast distributed semaphore implementation guarantees that
* threads invoking any of the {@link #acquire() acquire} methods are selected
* to obtain permits in the order in which their invocation of those methods
* was processed(first-in-first-out; FIFO). Note that FIFO ordering necessarily
* applies to specific internal points of execution within the cluster. Therefore,
* it is possible for one member to invoke {@code acquire} before another, but reach
* the ordering point after the other, and similarly upon return from the method.
* This class also provides convenience methods to {@link
* #acquire(int) acquire} and {@link #release(int) release} multiple
* permits at a time. Beware of the increased risk of indefinite
* postponement when using the multiple acquire. If a single permit is
* released to a semaphore that is currently blocking, 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.
*
*
*/
public interface ISemaphore extends DistributedObject {
/**
* Returns the name of this ISemaphore instance.
*
* @return name of this instance
*/
String getName();
/**
* Try to initialize this ISemaphore instance with the given permit count
*
* @param permits the given permit count
* @return true if initialization success
*/
boolean init(int permits);
/**
* Acquires a permit if one is available, and returns immediately,
* reducing the number of available permits 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:
*
* - some other thread invokes one of the {@link #release} methods for this
* semaphore and the current thread is next to be assigned a permit,
*
- this ISemaphore instance is destroyed, or
*
- some other thread {@linkplain Thread#interrupt interrupts}
* the current thread.
*
* If the current thread:
*
* - has its interrupted status set on entry to this method; or
*
- is {@linkplain Thread#interrupt interrupted} while waiting
* for a permit,
*
* then {@link InterruptedException} is thrown and the current thread's
* interrupted status is cleared.
*
* @throws InterruptedException if the current thread is interrupted
* @throws IllegalStateException if hazelcast instance is shutdown while waiting
*/
void acquire() throws InterruptedException;
/**
* Acquires the given number of permits if they are available,
* and returns immediately, reducing the number of available permits
* by the given amount.
*
* If insufficient permits are available then the current thread becomes
* disabled for thread scheduling purposes and lies dormant until
* one of three things happens:
*
* - some other thread invokes one of the {@link #release() release}
* methods for this semaphore, the current thread is next to be assigned
* permits and the number of available permits satisfies this request,
*
- this ISemaphore instance is destroyed, or
*
- some other thread {@linkplain Thread#interrupt interrupts}
* the current thread.
*
*
* If the current thread:
*
* - has its interrupted status set on entry to this method, or
*
- is {@linkplain Thread#interrupt interrupted} while waiting
* for a permit,
*
* then {@link InterruptedException} is thrown and the current thread's
* interrupted status is cleared.
*
* @param permits the number of permits to acquire
* @throws InterruptedException if the current thread is interrupted
* @throws IllegalArgumentException if {@code permits} is negative
* @throws IllegalStateException if hazelcast instance is shutdown while waiting
*/
void acquire(int permits) throws InterruptedException;
/**
* Returns the current number of permits currently available in this semaphore.
*
* - This method is typically used for debugging and testing purposes.
*
*
* @return the number of permits available in this semaphore
*/
int availablePermits();
/**
* Acquires and returns all permits that are immediately available.
*
* @return the number of permits drained
*/
int drainPermits();
/**
* Shrinks the number of available permits by the indicated
* reduction. This method differs from {@code acquire} in that it does not
* block waiting for permits to become available.
*
* @param reduction the number of permits to remove
* @throws IllegalArgumentException if {@code reduction} is negative
*/
void reducePermits(int reduction);
/**
* Releases a permit, increasing the number of available permits by
* one. If any threads in the cluster are trying to acquire a permit,
* then one is selected and given the permit that was just released.
*
* There is no requirement that a thread that releases a permit must
* have acquired that permit by calling one of the {@link #acquire() acquire} methods.
* Correct usage of a semaphore is established by programming convention
* in the application.
*/
void release();
/**
* Releases the given number of permits, increasing the number of
* available permits by that amount.
*
* There is no requirement that a thread that releases a permit must
* have acquired that permit by calling one of the {@link #acquire() acquire} methods.
* Correct usage of a semaphore is established by programming convention
* in the application.
*
* @param permits the number of permits to release
* @throws IllegalArgumentException if {@code permits} is negative
*/
void release(int permits);
/**
* Acquires a permit, if one is available and returns immediately,
* with the value {@code true},
* reducing the number of available permits by one.
*
* If no permit is available then this method will return
* immediately with the value {@code false}.
*
* @return {@code true} if a permit was acquired and {@code false}
* otherwise
*/
boolean tryAcquire();
/**
* Acquires the given number of permits, if they are available, and
* returns immediately, with the value {@code true},
* reducing the number of available permits by the given amount.
*
* If insufficient permits are available then this method will return
* immediately with the value {@code false} and the number of available
* permits is unchanged.
*
* @param permits the number of permits to acquire
* @return {@code true} if the permits were acquired and
* {@code false} otherwise
* @throws IllegalArgumentException if {@code permits} is negative
*/
boolean tryAcquire(int permits);
/**
* Acquires a permit from this semaphore if one becomes available
* within the given waiting time and the current thread has not
* been {@linkplain Thread#interrupt interrupted}.
*
* Acquires a permit if one is available and returns immediately
* with the value {@code true},
* reducing the number of available permits 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:
*
* - some other thread invokes the {@link #release} method for this
* semaphore and the current thread is next to be assigned a permit, or
*
- some other thread {@linkplain Thread#interrupt interrupts}
* the current thread, or
*
- the specified waiting time elapses.
*
*
* If a permit is acquired then the value {@code true} is returned.
*
* If the specified waiting time elapses then the value {@code false}
* is returned. If the time is less than or equal to zero, the method
* will not wait at all.
*
* If the current thread:
*
* - has its interrupted status set on entry to this method; or
*
- is {@linkplain Thread#interrupt interrupted} while waiting
* for a permit,
*
* then {@link InterruptedException} is thrown and the current thread's
* interrupted status is cleared.
*
* @param timeout the maximum time to wait for a permit
* @param unit the time unit of the {@code timeout} argument
* @return {@code true} if a permit was acquired and {@code false}
* if the waiting time elapsed before a permit was acquired
* @throws InterruptedException if the current thread is interrupted
* @throws IllegalStateException if hazelcast instance is shutdown while waiting
*/
boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException;
/**
* Acquires the given number of permits if they are available and
* returns immediately with the value {@code true},
* reducing the number of available permits by the given amount.
*
* If insufficient permits are available, then
* the current thread becomes disabled for thread scheduling
* purposes and lies dormant until one of three things happens:
*
* - some other thread invokes one of the {@link #release() release}
* methods for this semaphore, the current thread is next to be assigned
* permits and the number of available permits satisfies this request, or
*
- some other thread {@linkplain Thread#interrupt interrupts}
* the current thread, or
*
- the specified waiting time elapses.
*
*
* If the permits are acquired then {@code true} is returned.
*
* If the specified waiting time elapses then {@code false}
* is returned. If the time is less than or equal to zero, the method
* will not wait at all.
*
* If the current thread:
*
* - has its interrupted status set on entry to this method, or
*
- is {@linkplain Thread#interrupt interrupted} while waiting
* for a permit,
*
* then {@link InterruptedException} is thrown and the current thread's
* interrupted status is cleared.
*
* @param permits the number of permits to acquire
* @param timeout the maximum time to wait for the permits
* @param unit the time unit of the {@code timeout} argument
* @return {@code true} if all permits were acquired, {@code false}
* if the waiting time elapsed before all permits could be acquired
* @throws InterruptedException if the current thread is interrupted
* @throws IllegalArgumentException if {@code permits} is negative
* @throws IllegalStateException if hazelcast instance is shutdown while waiting
*/
boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException;
}