Java条件接口
时间:2020-01-09 10:35:11 来源:igfitidea点击:
驻留在java.util.concurrent.locks中的条件接口具有与对象类监视器方法类似的线程间通信方法(wait,notify和notifyAll)。条件提供了诸如await(),signal(),signalAll()之类的方法。如果Lock替换了同步方法和语句的使用,而Condition替换了Object监视器方法的使用。
下面给出了java.util.concurrent.locks.Condition接口中定义的一些方法。
- await()–使当前线程等待,直到被信号通知或者中断为止。
- await(长时间,TimeUnit单位)–使当前线程等待,直到发出信号或者被中断或者经过指定的等待时间为止。
- awaitNanos(long nanosTimeout)–使当前线程等待,直到被信号通知或者中断,或者经过了指定的等待时间。
- awaitUninterruptible()–使当前线程等待,直到发出信号为止。
- awaitUntil(日期截止时间)–使当前线程等待,直到发出信号或者被中断或者指定的截止时间过去为止。
- signal()–唤醒一个等待线程。
- signalAll()–唤醒所有等待的线程。
如何获得条件实例
Condition实例从本质上绑定到锁。要获取特定Lock实例的Condition实例,请使用其newCondition()方法。
使用Condition接口方法的示例
随后的生产者消费者程序使用Condition接口的方法在两个线程之间进行互通。
在示例中,消费者线程仅在缓冲区已满时才开始从缓冲区中删除项目,直到那时消费者线程由于await()方法而处于等待状态。
package com.theitroad.proj.Programs; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ProduceConsume { public static void main(String[] args) { int capacity = 5; // shared object Buffer buffer = new Buffer(capacity); Thread t1 = new Thread(new Producer(buffer, capacity), "Producer"); Thread t2 = new Thread(new Consumer(buffer, capacity), "Consumer"); t1.start(); t2.start(); } // Producer class to add elements to buffer static class Producer implements Runnable{ Buffer buffer; int capacity; Producer(Buffer buffer, int capacity){ this.buffer = buffer; this.capacity = capacity; } @Override public void run() { for(int i = 1; i <= capacity; i++){ try { buffer.put(i); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } // Consumer class to remove elements from buffer static class Consumer implements Runnable{ Buffer buffer; int capacity; Consumer(Buffer buffer, int capacity){ this.buffer = buffer; this.capacity = capacity; } @Override public void run() { for(int i = 1; i <= capacity; i++){ try { System.out.println("Item removed- " + buffer.take()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } static class Buffer { private Object[] items; final Lock lock = new ReentrantLock(); // Conditions final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); int putptr, takeptr, count; public Buffer(int capacity){ items = new Object[capacity]; } public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; System.out.println("Putting- "+ x); if (++putptr == items.length) { putptr = 0; } ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) { notEmpty.await(); } Object item = items[takeptr]; if (++takeptr == items.length) { takeptr = 0; } --count; notFull.signal(); return item; } finally { lock.unlock(); } } } }
输出:
Putting- 1 Putting- 2 Putting- 3 Putting- 4 Putting- 5 Item removed- 1 Item removed- 2 Item removed- 3 Item removed- 4 Item removed- 5