Créer un site internet

Multithreading

Semaphores

Definition

A counting semaphore.  Conceptually, a semaphore maintains a set of permits.  Each blocks if necessary until a permit is available, and then takes it.  Each 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. Semaphores are often used to restrict the number of threads than can access some (physical or logical) resource. For example, here isa class that uses a semaphore to control access to a pool of items:
 

package com.wmp;

import java.util.concurrent.Semaphore;

/**
 * PackageName com.wmp
 * Created by mhi on 08/11/2017.
 */
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();
  }

  protected Object[] items = new String[10];// ... 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;
  }
}

Step by Step

An easy way to get used to semaphores is to experiment, let's consider this sample code:

 

Semaphore sem = new Semaphore(1); 

try
{
  sem.acquire();
  System.out.println("Current available Permits: "+sem.availablePermits());
  sem.release();
  System.out.println("Current available Permits: "+sem.availablePermits());
}
catch (InterruptedException e)
{
  e.printStackTrace();
}

here is the result of the execution:

Current available Permits: 0
Current available Permits: 1

Description:

we created the object sem of the class semaphore with one available permit, then we called the method acquire on sem which  requests to get a permit if it is available, that's why the first permit value printed was 0 then after release we got back 1