Java Eşzamanlılığı - Koşul Arabirimi

Bir java.util.concurrent.locks.Condition arayüzü, verilen koşul doğru olana kadar iş parçacığının yürütülmesini askıya almasını sağlar. Bir Koşul nesnesi mutlaka bir Kilide bağlıdır ve newCondition () yöntemi kullanılarak elde edilmelidir.

Koşul Yöntemleri

Koşul sınıfında bulunan önemli yöntemlerin listesi aşağıdadır.

Sr.No. Yöntem ve Açıklama
1

public void await()

Mevcut iş parçacığının sinyal verilinceye veya kesilinceye kadar beklemesine neden olur.

2

public boolean await(long time, TimeUnit unit)

Mevcut iş parçacığının sinyal verilinceye veya kesilene kadar veya belirlenen bekleme süresi geçene kadar beklemesine neden olur.

3

public long awaitNanos(long nanosTimeout)

Mevcut iş parçacığının sinyal verilinceye veya kesilene kadar veya belirlenen bekleme süresi geçene kadar beklemesine neden olur.

4

public long awaitUninterruptibly()

Mevcut iş parçacığının sinyal verilinceye kadar beklemesine neden olur.

5

public long awaitUntil()

Mevcut iş parçacığının sinyal verilinceye veya kesilene kadar veya belirtilen son tarih geçene kadar beklemesine neden olur.

6

public void signal()

Bekleyen bir ileti dizisini uyandırır.

7

public void signalAll()

Tüm bekleyen konuları uyandırır.

Misal

Aşağıdaki TestThread programı, Koşul arabiriminin bu yöntemlerini gösterir. Burada iş parçacığının askıya alınmasını bildirmek ve beklemek () için signal () kullandık.

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

Bu, aşağıdaki sonucu verecektir.

Çıktı

[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