Conndition是什么?
{@code Condition} factors out the {@code Object} monitor
- methods ({@link Object#wait() wait}, {@link Object#notify notify}
- and {@link Object#notifyAll notifyAll}) into distinct objects to
- give the effect of having multiple wait-sets per object, by
- combining them with the use of arbitrary {@link Lock} implementations.
就是: Condition將Object的監(jiān)視器方法wait, notify, notifyall 分別實現(xiàn)為一個對象品洛,
用condition替代Object的監(jiān)視器方法锰提,condition與lock配合使用,新建一個condition
的方法condition=lock.newCondition(), 一個lock可以新建多個condition.
利用conditon實現(xiàn)生產(chǎn)者消費者模型
package com.cy.util.lock;
import com.cy.util.container.CycleArray;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionStudy {
final Lock lock = new ReentrantLock();
final Condition producterCondition = lock.newCondition();
final Condition consumerCondition = lock.newCondition();
final CycleArray<Integer> queue = new CycleArray<Integer>(10);
public boolean produce(Integer value) throws InterruptedException {
lock.lock();
try {
while (queue.isFull()) {
producterCondition.await();
}
queue.add(value);
System.out.println("add : " + value);
consumerCondition.signal();
return true;
} finally {
lock.unlock();
}
}
public Integer consume() throws InterruptedException {
lock.lock();
try {
while (queue.isEmpty()) {
consumerCondition.await();
}
Integer value = queue.get();
producterCondition.signal();
System.out.println("get : " + value);
return value;
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
final ConditionStudy conditionStudy = new ConditionStudy();
Thread consumer = new Thread(new Runnable() {
@Override
public void run() {
try {
for (int i = 0; i < 10000; i++) {
conditionStudy.consume();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
consumer.start();
Thread producer = new Thread(new Runnable() {
@Override
public void run() {
try {
for (int i = 0; i < 10000; i++) {
conditionStudy.produce(i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
producer.start();
}
}
CycleArray.java
package com.cy.util.container;
public class CycleArray<E> {
private E[] values;
private int head = -1;
private int tail = 0;
private int capacity;
public CycleArray(int capacity) {
values = (E[]) new Object[capacity];
this.capacity = capacity;
}
public boolean add(E value) {
if (head != tail) {
values[tail] = value;
if (head == -1) {
head = tail;
}
tail = (tail + 1) % capacity;
return true;
} else {
return false;
}
}
public E get() {
if (head == -1) {
return null;
} else {
E value = values[head];
head = (head + 1) % capacity;
head = head == tail ? -1 : head;
return value;
}
}
public boolean isEmpty() {
return head == -1;
}
public boolean isFull() {
return head == tail;
}
}