Java Language Sémaphore


Exemple

Un sémaphore est un synchroniseur de haut niveau qui conserve un ensemble d' autorisations pouvant être acquises et libérées par les threads. Un sémaphore peut être imaginé comme un compteur de permis qui sera décrémenté lorsqu'un fil acquiert et incrémenté lors de la sortie d'un thread. Si le nombre de permis est égal à 0 lorsqu'un thread tente d'acquérir, le thread se bloque jusqu'à ce qu'un permis soit disponible (ou jusqu'à ce que le thread soit interrompu).

Un sémaphore est initialisé comme:

Semaphore semaphore = new Semaphore(1); // The int value being the number of permits

Le constructeur Semaphore accepte un paramètre booléen supplémentaire pour l'équité. Lorsqu'elle est définie sur false, cette classe ne garantit pas l'ordre dans lequel les threads acquièrent l'autorisation. Lorsque l'équité est définie sur true, le sémaphore garantit que les threads appelant l'une des méthodes d'acquisition sont sélectionnés pour obtenir les autorisations dans l'ordre dans lequel leur appel de ces méthodes a été traité. Il est déclaré de la manière suivante:

Semaphore semaphore = new Semaphore(1, true);

Examinons maintenant un exemple de javadocs, où Semaphore est utilisé pour contrôler l'accès à un pool d'éléments. Un sémaphore est utilisé dans cet exemple pour fournir une fonctionnalité de blocage afin de s’assurer qu’il ya toujours des éléments à obtenir lorsque getItem() est appelé.

class Pool {
    /*
     * Note that this DOES NOT bound the amount that may be released!
     * This is only a starting value for the Semaphore and has no other
     * significant meaning UNLESS you enforce this inside of the
     * getNextAvailableItem() and markAsUnused() methods
     */
    private static final int MAX_AVAILABLE = 100;
    private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);

    /**
     * Obtains the next available item and reduces the permit count by 1. 
     * If there are no items available, block.
     */
    public Object getItem() throws InterruptedException {
        available.acquire();
        return getNextAvailableItem();
    }

    /**
     * Puts the item into the pool and add 1 permit.
     */
    public void putItem(Object x) {
        if (markAsUnused(x))
            available.release();
    }

    private Object getNextAvailableItem() {
        // Implementation
    }

    private boolean markAsUnused(Object o) {
        // Implementation
    }
}