bf1,bf2是两个大小各为3的条件队列。3将要put进bf1,此时因为bf1已满而已调用wait()方法挂起线程,此时若对bf2()执行take()方法并调用notifyall()是否会唤醒wait()中的bf1?(对两个队列的操作存在于两个不同的线程中)
先上代码
public abstract class BaseBoundedBuffer<V>{
private final V[] buf;
private int tail;
private int head;
private int count;
protected BaseBoundedBuffer(int capacity) {
this.buf = (V[]) new Object[capacity];
}
protected synchronized final void doPut(V v){
buf[tail]=v;
if (++tail==buf.length){
tail=0;
}
++count;
}
protected synchronized final V doTake(){
V v=buf[head];
buf[head]=null;
if (++head == buf.length){
head=0;
}
--count;
return v;
}
public synchronized final boolean isFull(){
return count==buf.length;
}
public synchronized final boolean isEmpty(){
return count==0;
}
}
public class BoundedBuffer<V> extends BaseBoundedBuffer {
private int id;
protected BoundedBuffer(int capacity,int id) {
super(capacity);
this.id=id;
}
public synchronized void put(V v)throws InterruptedException{ //对条件队列执行增加元素的操作
while (isFull()){
System.out.println(id+"快睡了------put");
wait();
System.out.println(id+"醒了--------put");
}
doPut(v);
System.out.println(id+"put"+v);
notifyAll();
}
public synchronized V take() throws InterruptedException{ //对条件队列执行读取操作
while (isEmpty()){
System.out.println(id+"快睡了--------take");
wait();
System.out.println(id+"醒了----------take");
}
V v= (V) doTake();
notifyAll();
return v;
}
}
public class BufferTest {
public static void main(String[] args) throws InterruptedException {
BoundedBuffer bf =new BoundedBuffer(3,1);
BoundedBuffer bf2=new BoundedBuffer(3,2);
bf2.put(9999999);
new Thread(){
public void run(){
for (int i=0;i<4;i++){
try {
bf.put(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
new Thread(){
public void run(){
try {
System.out.println( bf2.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
}
执行结果如下
2put9999999
1put0
1put1
1put2
1快睡了------put
9999999
在执行结果第五行的时候便是上图所描述的情况(3想要put进bf1,但是因为已经full,bf1进入wait()状态),第六行输出了9999999,也就说明bf2执行了take()操作,同时也执行了notifyAll()方法,然而对bf1没有产生任何影响。
V v= (V) doTake();
notifyAll();
return v;
结果证明: 在使用条件队列时候,notifyAll()只会唤醒同一对象因执行wait()被挂起的线程