简介:之前文章中介绍过线程间通信示例,里面的用到了Object.wait和Object.notify,同时也知晓这两个方法要配合synchronized关键字使用,synchronized依赖于JVM,实现机制都在虚拟机层面,并没有暴露给我们。作为Lock系列功能中的Condition接口配合lock锁是可以替代Object监视器方法,依赖于API,它具有很好的灵活性。
方法:
示例:为了更好的理解Lock和Condition的使用场景,下面我们使用多线程实现一个产品容器,生产者负责生产,消费者负责消费。这里我们使用lock的newCondition()获取对象,signal()通知和await()挂起线程。
public class TestCondition {
public static void main(String[] args) throws InterruptedException{
//容器限量为10个
ItemQueue itemQueue = new ItemQueue(10);
Thread producer = new Producer(itemQueue);
Thread consumer = new Consumer(itemQueue);
producer.start();
consumer.start();
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();
}
/**
* 生产产品放入容器的方法
* @param item
* @throws InterruptedException
*/
public void add(Object item) throws InterruptedException{
lock.lock();
while(current >= items.length) isFull.await();
items[placeIndex] = item;
placeIndex = (placeIndex + 1) % items.length;
++current;
isEmpty.signal();
lock.unlock();
}
/**
* 消费容器中的产品方法
* @return
* @throws InterruptedException
*/
public Object remove() throws InterruptedException{
Object item = null;
lock.lock();
while(current <= 0){
isEmpty.await();
}
item = items[removeIndex];
items[removeIndex]=null;
removeIndex = (removeIndex+1) % items.length;
--current;
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;
}
public void run(){
String[] numbers = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12","13", "14", "15"};
try {
for (String number : numbers) {
queue.add(number);
System.out.println("[Producer]:"+number);
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
//消费者
static class Consumer extends Thread{
private final ItemQueue queue;
public Consumer(ItemQueue queue) {
this.queue =queue;
}
public void run() {
try {
do {
Object number = queue.remove();
System.out.println("[Consumer]:"+number);
if(number == null){
return;
}
} while (!queue.isEmpty());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
结果: