Java Concurrency - Antarmuka Kondisi

Antarmuka java.util.concurrent.locks.Condition menyediakan kemampuan utas untuk menangguhkan eksekusinya, hingga kondisi yang diberikan benar. Objek Kondisi harus terikat ke Lock dan diperoleh menggunakan metode newCondition ().

Metode Kondisi

Berikut adalah daftar metode penting yang tersedia di kelas Kondisi.

Sr.No. Metode & Deskripsi
1

public void await()

Menyebabkan utas saat ini menunggu hingga diberi sinyal atau terputus.

2

public boolean await(long time, TimeUnit unit)

Menyebabkan utas saat ini menunggu hingga diberi sinyal atau terputus, atau waktu tunggu yang ditentukan berlalu.

3

public long awaitNanos(long nanosTimeout)

Menyebabkan utas saat ini menunggu hingga diberi sinyal atau terputus, atau waktu tunggu yang ditentukan berlalu.

4

public long awaitUninterruptibly()

Menyebabkan utas saat ini menunggu hingga diberi sinyal.

5

public long awaitUntil()

Menyebabkan utas saat ini menunggu hingga diberi sinyal atau terputus, atau tenggat waktu yang ditentukan berlalu.

6

public void signal()

Bangun satu utas menunggu.

7

public void signalAll()

Bangun semua utas menunggu.

Contoh

Program TestThread berikut mendemonstrasikan metode antarmuka Kondisi ini. Di sini kita telah menggunakan signal () untuk memberi tahu dan menunggu () untuk menangguhkan utas.

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

Ini akan menghasilkan hasil sebagai berikut.

Keluaran

[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