10 Java并发Condition接口

作者: 笑Skr人啊 | 来源:发表于2017-08-31 13:52 被阅读22次

    java.util.concurrent.locks.Condition接口提供一个线程挂起执行的能力,直到给定的条件为真。 Condition对象必须绑定到Lock,并使用newCondition()方法获取对象。

    Condition类的方法

    以下是Condition类中可用的重要方法的列表。

    序号 方法名称 描述
    1 public void await() 使当前线程等待,直到发出信号或中断信号。
    2 public boolean await(long time, TimeUnit unit) 使当前线程等待直到发出信号或中断,或指定的等待时间过去。
    3 public long awaitNanos(long nanosTimeout) 使当前线程等待直到发出信号或中断,或指定的等待时间过去。
    4 public long awaitUninterruptibly() 使当前线程等待直到发出信号。
    5 public long awaitUntil() 使当前线程等待直到发出信号或中断,或者指定的最后期限过去。
    6 public void signal() 唤醒一个等待线程。
    7 public void signalAll() 唤醒所有等待线程。

    实例

    以下ConditionTest程序演示了Condition接口的这些方法。这里我们使用signal()通知和await()挂起线程。

    package ThreadMethod;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class ConditionTest {
    
       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){
                   queue.add(number);
                   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();
             }
          }
       }
    }
    

    运行

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

    相关文章

      网友评论

        本文标题:10 Java并发Condition接口

        本文链接:https://www.haomeiwen.com/subject/pljqjxtx.html