Java Concurrency - Giao diện điều kiện

Giao diện java.util.concurrent.locks.Condition cung cấp khả năng tạm dừng việc thực thi của luồng cho đến khi điều kiện đã cho là đúng. Đối tượng Điều kiện nhất thiết phải liên kết với Khóa và được lấy bằng phương thức newCondition ().

Phương pháp điều kiện

Sau đây là danh sách các phương thức quan trọng có sẵn trong lớp Điều kiện.

Sr.No. Phương pháp & Mô tả
1

public void await()

Làm cho luồng hiện tại đợi cho đến khi nó được báo hiệu hoặc bị ngắt.

2

public boolean await(long time, TimeUnit unit)

Làm cho luồng hiện tại đợi cho đến khi nó được báo hiệu hoặc bị ngắt, hoặc thời gian chờ đã chỉ định trôi qua.

3

public long awaitNanos(long nanosTimeout)

Làm cho luồng hiện tại đợi cho đến khi nó được báo hiệu hoặc bị ngắt, hoặc thời gian chờ đã chỉ định trôi qua.

4

public long awaitUninterruptibly()

Làm cho luồng hiện tại đợi cho đến khi nó được báo hiệu.

5

public long awaitUntil()

Làm cho luồng hiện tại đợi cho đến khi nó được báo hiệu hoặc bị gián đoạn, hoặc thời hạn được chỉ định trôi qua.

6

public void signal()

Đánh thức một chuỗi đang chờ.

7

public void signalAll()

Đánh thức tất cả các chủ đề đang chờ.

Thí dụ

Chương trình TestThread sau đây trình bày các phương thức này của giao diện Điều kiện. Ở đây chúng tôi đã sử dụng signal () để thông báo và chờ đợi () để tạm dừng luồng.

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

Điều này sẽ tạo ra kết quả sau.

Đầu ra

[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