首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用JAVA多线程的多个生产者和使用者

使用JAVA多线程的多个生产者和使用者
EN

Stack Overflow用户
提问于 2020-07-10 09:12:48
回答 1查看 120关注 0票数 0

我被困在这个关于多个生产者-消费者问题的问题中。我的目标是写六个线程作为A,B,…,F,并让程序永远打印。

请点击这里获取图片:点击

每个与箭头相关联的节点对应于生产者-消费者对(或者说buffer)。缓冲区大小为2,最初只有A拥有2个令牌。我已经尝试过A -> B -> D ->F。代码如下:

代码语言:javascript
运行
复制
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();
    }
}
代码语言:javascript
运行
复制
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");
        }
    }
}
代码语言:javascript
运行
复制
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();

    }
}

输出(我截图开头和中间):

click1 click2

我试着认为它是主人(生产者),狗(消费者)和曲奇(产品)。主人放了饼干,狗就吃了。

我的问题是:

  1. 输出看起来像最初100个cookie中的第一张图片(AtoB& BtoD)。然后,它转到了第二幅图片(BtoD & DtoF),直到1万。我怎么才能解决呢?我也希望它能让AtoB运行,但它停止了.
  2. 我不知道怎么从A和F开始,因为他们有两次出局。
  3. 我的策略对吗?我编写的代码是基于单一生产者-消费者场景的。

我不熟悉多线程,所以请告诉我我的错误。非常感谢!

EN

回答 1

Stack Overflow用户

发布于 2020-07-10 10:39:48

首先,虽然“同步”对于互斥仍然有效,但对于信令来说,它已经过时了15年。如果您想要等待/通知,请使用可重入的锁和条件等待/信号所有。

通知()只唤醒一个线程,这很可能是错误的线程,因为您没有信号的任何条件。最后一个put线程将缓冲区设置为2(完全)可能会通知另一个put线程,然后不会发生更多的通知来唤醒吃者。

旧的方法是使用notifyAll(),虽然这会唤醒每个人,并导致很多争用来获得同步,除了一个或两个线程之外,什么都不需要。这就是为什么您应该更喜欢带有两个条件的重入锁(不是空的/不满的)。

这几乎是排在队列后面的基础。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62830997

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档