使用多线程的生产者消费者计划

时间:2013-11-19 05:46:40

标签: java multithreading producer-consumer

我正在尝试使用java实现标准的Producer Consumer问题。

我做了一些代码来完成它。

以下是代码:

制作人类:

class Producer implements Runnable
{

public Producer()
{
    new Thread(this,"Producer").start();
}

public synchronized void put()
{
    while(Q.valueset)
    {
        try
        {
            wait();
        }
        catch(Exception e)
        {
            System.out.println(e);
        }
    }
    Q.valueset=true;
    Q.i++;
    System.out.println("Put:"+Q.i);
    notify();
}
public void run()
{
    while(true)
    {
        put();
    }
}
}

消费者类:

class Consumer implements Runnable
{
public Consumer()
{
    new Thread(this,"Consumer").start();
}

public synchronized void get()
{
    while(!Q.valueset)
    {
        try
        {
            wait();
        }
        catch(Exception e)
        {
            System.out.println(e);
        }
    }
    Q.valueset=false;
    notify();
    System.out.println("Get:"+Q.i);
}

public void run()
{
    while(true)
    {
        get();
    }

}
}

静态变量的另一个类:

class Q
{
static boolean valueset=false;
static int i;
}

我还有一个只包含main的类,并创建了Producer和Consumer的实例。

现在,当我尝试运行此程序时,它会提供以下输出:

Put:1
put:2
Got:1
Got:2

我对Wait()和notify()有误解,认为它是如何工作的,以及对象是如何从monitor进入和离开的。我想清除这个概念。

此问题也是由于Wait和notify()引起的。

我知道这是与多线程相关的非常基本的问题,但这些将帮助我清除我的误解。

我还想了解代码中的问题。

我已经通过以下链接:

producer - consumer multithreading in Java

2 个答案:

答案 0 :(得分:2)

您需要在某个共享对象上wait()notify()。您现在使用synchronized执行的操作是等待相应的对象本身,即Producer正在等待Producer和Consumer对象上的Consumer。你需要在Q中等待一些事情。

来自Javadoc:

  

notify():唤醒正在等待此对象的监视器的单个线程。

     

wait():当前线程必须拥有此对象的监视器。线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。然后该线程等待,直到它可以重新获得监视器的所有权并继续执行。

此对象的监视器在您的案例中为this,这是Producer案例中的put()和{Consumer中的get() 1}}案例。但是为了让通知通知另一个线程,它们需要具有相同的监视器,即它们需要在同一对象上wait()。该对象可以是例如Q中的对象变量。

为了让你开始,这就是我的意思:

class Q
{
static boolean valueset=false;
static int i;
static Object myLock = new Object();
}

public void put() {
    synchronized (Q.myLock) { 
        while (Q.valueset) {
            try {
                Q.myLock.wait();
            } catch (Exception e) {
                System.out.println(e);
            }
        }
        Q.i++; //you forgot this as well
        System.out.println("Put:" + Q.i);
        Q.valueset = true;
        Q.myLock.notify();
    }
}

您可以自己填写消费者类......

Put:1
Get:1
Put:2
Get:2
Put:3
Get:3
Put:4
Get:4

答案 1 :(得分:0)

这篇文章解释了通知,等待和你正在寻找的其他事情之间的关系。

Difference between wait() and sleep()