Concurrence Java - Interface de condition

Une interface java.util.concurrent.locks.Condition fournit à un thread la capacité de suspendre son exécution, jusqu'à ce que la condition donnée soit vraie. Un objet Condition est nécessairement lié à un Lock et doit être obtenu à l'aide de la méthode newCondition ().

Méthodes de condition

Voici la liste des méthodes importantes disponibles dans la classe Condition.

N ° Sr. Méthode et description
1

public void await()

Fait attendre le thread actuel jusqu'à ce qu'il soit signalé ou interrompu.

2

public boolean await(long time, TimeUnit unit)

Fait attendre le thread actuel jusqu'à ce qu'il soit signalé ou interrompu, ou que le temps d'attente spécifié s'écoule.

3

public long awaitNanos(long nanosTimeout)

Fait attendre le thread actuel jusqu'à ce qu'il soit signalé ou interrompu, ou que le temps d'attente spécifié s'écoule.

4

public long awaitUninterruptibly()

Fait attendre le thread actuel jusqu'à ce qu'il soit signalé.

5

public long awaitUntil()

Fait attendre le thread actuel jusqu'à ce qu'il soit signalé ou interrompu, ou que le délai spécifié soit écoulé.

6

public void signal()

Réveille un fil d'attente.

sept

public void signalAll()

Réveille tous les threads en attente.

Exemple

Le programme TestThread suivant illustre ces méthodes de l'interface Condition. Ici, nous avons utilisé signal () pour notifier et wait () pour suspendre le thread.

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestThread {

   public static void main(String[] args) throws InterruptedException {
      ItemQueue itemQueue = new ItemQueue(10);

      //Create a producer and a consumer.
      Thread producer = new Producer(itemQueue);
      Thread consumer = new Consumer(itemQueue);

      //Start both threads.
      producer.start();
      consumer.start();

      //Wait for both threads to terminate.
      producer.join();
      consumer.join();
   }

   static class ItemQueue {
      private Object[] items = null;
      private int current = 0;
      private int placeIndex = 0;
      private int removeIndex = 0;

      private final Lock lock;
      private final Condition isEmpty;
      private final Condition isFull;

      public ItemQueue(int capacity) {
         this.items = new Object[capacity];
         lock = new ReentrantLock();
         isEmpty = lock.newCondition();
         isFull = lock.newCondition();
      }

      public void add(Object item) throws InterruptedException {
         lock.lock();

         while(current >= items.length)
            isFull.await();

         items[placeIndex] = item;
         placeIndex = (placeIndex + 1) % items.length;
         ++current;

         //Notify the consumer that there is data available.
         isEmpty.signal();
         lock.unlock();
      }

      public Object remove() throws InterruptedException {
         Object item = null;

         lock.lock();

         while(current <= 0) {
            isEmpty.await();
         }
         item = items[removeIndex];
         removeIndex = (removeIndex + 1) % items.length;
         --current;

         //Notify the producer that there is space available.
         isFull.signal();
         lock.unlock();

         return item;
      }

      public boolean isEmpty() {
         return (items.length == 0);
      }
   }

   static class Producer extends Thread {
      private final ItemQueue queue;
      
      public Producer(ItemQueue queue) {
         this.queue = queue;
      }

      @Override
      public void run() {
         String[] numbers =
            {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"};

         try {
            
            for(String number: numbers) {
               System.out.println("[Producer]: " + number);
            }
            queue.add(null);
         } catch (InterruptedException ex) {
            ex.printStackTrace();
         } 
      }
   }

   static class Consumer extends Thread {
      private final ItemQueue queue;
      
      public Consumer(ItemQueue queue) {
         this.queue = queue;
      }

      @Override
      public void run() {
         
         try {
            
            do {
               Object number = queue.remove();
               System.out.println("[Consumer]: " + number);

               if(number == null) {
                  return;
               }
            } while(!queue.isEmpty());
         } catch (InterruptedException ex) {
            ex.printStackTrace();
         }
      }
   }
}

Cela produira le résultat suivant.

Production

[Producer]: 1
[Producer]: 2
[Producer]: 3
[Producer]: 4
[Producer]: 5
[Producer]: 6
[Producer]: 7
[Producer]: 8
[Producer]: 9
[Producer]: 10
[Producer]: 11
[Producer]: 12
[Consumer]: null