首先是我的理解:
notify()
只会唤醒一个帖子。唤醒的线程将从wait()
继续。
public class T_SynList extends LinkedList<Item>{
public static int MAX=5;
public synchronized void produce(String producer)
{
while(size()==MAX)
{
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
add(new Item(producer,0));
notify();
}
public synchronized Item consume(String consumer)
{
//**My doubt!!!!!!!!**
while(size()==0)
{
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Item item=removeFirst();
item.setConsumer(consumer);
notify();
return item;
}
}
有1个生产者和5个消费者。如果我将while(size()==0)
更改为if(size()==0)
,则该过程将从size = 0的列表中获取错误(removeFirst())。
原因可能是同时唤醒两个消费者线程,但只有一个可以继续。但是文件说notify()只唤醒一个线程。为什么我不能做这样的改变?
答案 0 :(得分:0)
while(size() == 0)
非常重要。如果消费者被唤醒,他会检查自己是否有消费元素。如果没有,他会回去睡觉。
notify()
方法会在同一台显示器上唤醒一个主题(&#39;在您的情况下为#39;)。最终消费者在服用最后一个元素后唤醒另一个消费者是可能的
如果您使用if(size()==0)
其他消费者被唤醒,则尝试获取元素并出现错误。
你还必须使用notfyAll()
来唤醒所有线程,最快的是获取元素,所有其他线程将重新进入休眠状态。如果没有,你可能会陷入僵局。
p1 -> put element -> notify c1 -> sleep
c1 -> take element -> notify c2 -> sleep
c2 -> no element -> sleep -> not waking up anyone -> deadlock