我尝试了一个生产者消费者程序..有时输出是正确的,有时虽然程序运行完成,但输出中间会出现异常..
我明白IndexOutOfBoundsException
了,我相信原因如下:-当 Q 为空时,所有 3 个消费者线程都进入等待状态;当生产者添加一个项目并通知所有等待线程时,在消费者线程删除该项目后,唤醒的另一个消费者线程将尝试删除(当 Q 现在为空时)导致此问题.. 我知道这是一场比赛条件,但无法弄清楚如何避免它......欢迎任何想法/建议。
另一个查询 - 我无法找到优雅终止该程序的方法。截至目前,我已经使用System.exit(0)
了最后一个项目的生产时间。欢迎任何其他更好的想法。
附言
我不想使用任何 java 的 API 同步类,我想尝试使用wait()/notify()
机制..
class Producer implements Runnable
{
private Queue q;
Producer(Queue q)
{
this.q = q;
}
@Override
public void run() {
for(int i =0;i<50;i++)
try {
q.add(new Integer(i));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer extends Thread
{
private Queue q;
Consumer(Queue q)
{
this.q = q;
}
public void run()
{
try {
while(true)
{
System.out.println(Thread.currentThread().getName()+"-"+ q.get());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Main
{
public static void main(String args[])
{
Queue q = new Queue();
Producer runObj = new Producer(q);
Thread producerObj = new Thread(runObj,"Producer");
producerObj.start();
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
Consumer c3 = new Consumer(q);
c1.setName("c1");
c2.setName("c2");
c3.setName("c3");
c1.start();
c2.start();
c3.start();
}
}
队列类:
public class Queue {
private ArrayList<Integer> itemQ;
int qSize = 5;
Queue()
{
itemQ = new ArrayList<Integer>();
}
public synchronized void add(Integer item) throws InterruptedException
{
if(itemQ.size() == qSize)
{
System.out.println("Q is full");
wait();
}
System.out.println(item);
if(item.equals(new Integer(49)))
{
System.out.println("Out Of Stock");
System.exit(0);
}
itemQ.add(item);
notifyAll();
}
public synchronized Integer get() throws InterruptedException
{
if(itemQ.isEmpty())
{
wait();
}
Integer item = itemQ.remove(0);
notify();
return item;
}
}