Учебники

Параллелизм Java — интерфейс условий

Интерфейс java.util.concurrent.locks.Condition обеспечивает возможность потока приостановить его выполнение до тех пор, пока данное условие не станет истинным. Объект Condition обязательно связан с Lock и должен быть получен с помощью метода newCondition ().

Методы условий

Ниже приведен список важных методов, доступных в классе Condition.

Sr.No. Метод и описание
1

публичное недействительное ожидание ()

Заставляет текущий поток ждать, пока он не будет сигнализирован или прерван.

2

public boolean await (долгое время, единица времени)

Заставляет текущий поток ждать, пока он не будет сигнализирован или прерван, или пока не истечет указанное время ожидания.

3

публичные долгожданныеNanos (long nanosTimeout)

Заставляет текущий поток ждать, пока он не будет сигнализирован или прерван, или пока не истечет указанное время ожидания.

4

Публичный долгожданный бесперебойно ()

Заставляет текущий поток ждать, пока он не будет сигнализирован.

5

public long awaitUntil ()

Заставляет текущий поток ждать, пока он не будет сигнализирован или прерван, или пока не истечет указанный крайний срок.

6

публичный пустой сигнал ()

Просыпается одна ожидающая нить.

7

public void signalAll ()

Просыпается все ожидающие темы.

публичное недействительное ожидание ()

Заставляет текущий поток ждать, пока он не будет сигнализирован или прерван.

public boolean await (долгое время, единица времени)

Заставляет текущий поток ждать, пока он не будет сигнализирован или прерван, или пока не истечет указанное время ожидания.

публичные долгожданныеNanos (long nanosTimeout)

Заставляет текущий поток ждать, пока он не будет сигнализирован или прерван, или пока не истечет указанное время ожидания.

Публичный долгожданный бесперебойно ()

Заставляет текущий поток ждать, пока он не будет сигнализирован.

public long awaitUntil ()

Заставляет текущий поток ждать, пока он не будет сигнализирован или прерван, или пока не истечет указанный крайний срок.

публичный пустой сигнал ()

Просыпается одна ожидающая нить.

public void signalAll ()

Просыпается все ожидающие темы.

пример

Следующая программа TestThread демонстрирует эти методы интерфейса Condition. Здесь мы использовали signal () для уведомления и await () для приостановки потока.

Live Demo

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();
         }
      }
   }
}

Это даст следующий результат.