Java 使用多线程的生产者-消费者程序

Java 使用多线程的生产者-消费者程序,java,multithreading,producer-consumer,Java,Multithreading,Producer Consumer,我试图用java实现标准的生产者-消费者问题 我做了一些代码 代码如下: 制作人类别: class Producer implements Runnable { public Producer() { new Thread(this,"Producer").start(); } public synchronized void put() { while(Q.valueset) { try { wait();

我试图用java实现标准的生产者-消费者问题

我做了一些代码

代码如下:

制作人类别:

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;
}
消费者类别:

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;
}
另一个静态变量类:

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()的工作原理以及对象如何从监视器进出有误解。我想澄清这个概念

这里的问题也是由于等待和通知()引起的

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

我还想了解代码中的问题是什么

我已经浏览了以下链接:


这篇文章解释了通知、等待和其他您正在寻找的东西之间的关系

您需要对某个共享对象执行
wait()
notify()
。您现在使用synchronized所做的是等待各个对象本身,即生产者等待生产者,消费者等待消费者对象。你需要在Q中等待一些东西

从Javadoc:

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

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

在您的案例中,此对象的监视器是
,它是
put()
案例中的
生产者
,以及
get()
案例中的
消费者
。但是为了让notify通知另一个线程,它们需要有相同的监视器,也就是说,它们需要在同一个对象上
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

谢谢你的支持。我读了这些链接,但我想清楚地了解如何在我的程序中完美地使用这些方法?锁的作用是什么?对不起,我听不懂你说的。你的意思是什么?是的,你需要添加一个共享对象作为类Q的监视器:
staticobjectlock=newobject()
它不需要命名为
lock
,您也可以将其命名为
abcdefg
静态对象abcdefg=new Object()我无法理解“但是是的,您需要添加一个共享对象作为类Q:static object lock=new object()”的监视器;“您想说什么,我对锁行特别感到困惑。