我被困在这个关于多个生产者-消费者问题的问题中。我的目标是写六个线程作为A,B,…,F,并让程序永远打印。
请点击这里获取图片:点击
每个与箭头相关联的节点对应于生产者-消费者对(或者说buffer)。缓冲区大小为2,最初只有A拥有2个令牌。我已经尝试过A -> B -> D ->F。代码如下:
class Cookies
{
private int cookiesNo;
private int buffer=0;
public synchronized void put (int cNo, String sender, String receiver)
{
while (buffer==2)
{
try
{
wait();
}
catch (InterruptedException e){}
}
System.out.println(sender+" put the "+cNo+"th cookie to "+receiver);
cookiesNo= cNo;
buffer++;
notify();
}
public synchronized void eat (int cNo, String sender, String receiver)
{
while (buffer==0)
{
try {
wait();
}
catch (InterruptedException e){}
}
System.out.println(sender+" put the "+cNo+"th cookie to "+receiver);
cookiesNo= cNo;
buffer--;
notify();
}
}class DPut implements Runnable
{
Cookies cookies;
DPut(Cookies cookies)
{
this.cookies=cookies;
}
public void run()
{
for (int i=1; i<=10000; i++)
{
cookies.put(i, "D", "F");
}
}
}
class DEat implements Runnable //human
{
Cookies cookies;
DEat(Cookies cookies)
{
this.cookies=cookies;
}
public void run()
{
for (int i=1; i<=10000; i++)
{
cookies.eat(i, "B", "D");
}
}
}
class APut implements Runnable
{
Cookies cookies;
APut(Cookies cookies)
{
this.cookies=cookies;
}
public void run()
{
for (int i=1; i<=100; i++)
{
cookies.put(i, "A", "B");
}
}
}public class practice
{
public static void main(String[] args)
{
Cookies cookies= new Cookies();
DPut dput= new DPut(cookies);
DEat deat= new DEat(cookies);
APut aput= new APut(cookies);
Thread ddog= new Thread(deat);
Thread dmaster= new Thread(dput);
Thread amaster= new Thread(aput);
amaster.start();
ddog.start();
dmaster.start();
}
}输出(我截图开头和中间):
我试着认为它是主人(生产者),狗(消费者)和曲奇(产品)。主人放了饼干,狗就吃了。
我的问题是:
我不熟悉多线程,所以请告诉我我的错误。非常感谢!
发布于 2020-07-10 10:39:48
首先,虽然“同步”对于互斥仍然有效,但对于信令来说,它已经过时了15年。如果您想要等待/通知,请使用可重入的锁和条件等待/信号所有。
通知()只唤醒一个线程,这很可能是错误的线程,因为您没有信号的任何条件。最后一个put线程将缓冲区设置为2(完全)可能会通知另一个put线程,然后不会发生更多的通知来唤醒吃者。
旧的方法是使用notifyAll(),虽然这会唤醒每个人,并导致很多争用来获得同步,除了一个或两个线程之外,什么都不需要。这就是为什么您应该更喜欢带有两个条件的重入锁(不是空的/不满的)。
这几乎是排在队列后面的基础。
https://stackoverflow.com/questions/62830997
复制相似问题