All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.core.ISemaphore Maven / Gradle / Ivy

/*
 * Copyright (c) 2008-2018, 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. *

* During a split-brain scenario, atomicity is lost. The same ISemaphore can exist within each cluster * partition and therefore the permit counters within will diverge. When the cluster heals, Hazelcast * will choose one of the ISemaphores, by default this is selected from the largest partitioned cluster * (by number of members). If the cluster sizes are all equal then a random ISemaphore will be chosen. * * Supports Quorum {@link com.hazelcast.config.QuorumConfig} since 3.10 in cluster versions 3.10 and higher. */ 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); /** * Increases the number of available permits by the indicated * amount. This method differs from {@code release} in that it does not * effect the amount of permits this caller has attached. * * @param increase the number of permits to add * @throws IllegalArgumentException if {@code increase} is negative */ void increasePermits(int increase); /** * 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; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy