使用java线程在生产者消费者中的问题

时间:2016-02-22 05:11:40

标签: java multithreading

我已经编写了生产者消费者问题的代码,其中生产者生产该项目三次,然后只有消费者消费该项目一次。下面的代码作为一个要求正常工作,但主线程不会停止。我不知道为什么它不会停止,我无法捕捉到。你能不能请任何人查看下面的代码并更正它?

public class ProducerConsumerProblem
{

    public static void main(String[] args)
    {

    ProducerConsumerStack st = new ProducerConsumerStack();
    new ProducerThread(st);
    new ConsumerThread(st);

    }
}

class ProducerConsumerStack
{
    int x;
    boolean flag = false;
    int producedCount = 0;

    public synchronized void push(int x)
    {
    if (flag)
    { // flag==true
        try
        {
        wait();
        }
        catch (Exception e)
        {
        System.out.println(e);
        }
    }
    this.x = x;
    System.out.println(x + " is produced..");
    try
    {
        Thread.sleep(250);
    }
    catch (Exception e)
    {
        System.out.println(e);
    }

    this.producedCount++;
    if (this.producedCount == 3)
    {
        this.producedCount = 0;
        this.flag = true;
        notifyAll();
    }

    }

    synchronized public void pop()
    {
    if (!flag)
    { // flag==false
        try
        {
        wait();
        }
        catch (Exception e)
        {
        System.out.println(e);
        }
    }
    System.out.println(x + " is consumed.\n");
    try
    {
        Thread.sleep(1500);
    }
    catch (Exception e)
    {
        System.out.println(e);
    }
    flag = false;
    notify();
    }
}

class ProducerThread implements Runnable
{
    ProducerConsumerStack st = null;

    ProducerThread(ProducerConsumerStack st)
    {
    this.st = st;
    Thread t1 = new Thread(this);
    t1.start();
    }

    public void run()
    {
    int a = 1;
    for (int i = 0; i < 15; i++)
    {
        st.push(a++);
    }
    }
}

class ConsumerThread implements Runnable
{
    ProducerConsumerStack st = null;

    ConsumerThread(ProducerConsumerStack st)
    {
    this.st = st;
    Thread t2 = new Thread(this);
    t2.start();
    }

    public void run()
    {
    for (int i = 0; i < 15; i++)
    {
        st.pop();
    }
    }
}

1 个答案:

答案 0 :(得分:0)

  

@james large:请运行相同的代码,然后查看主线程是否正在完成。它根本不会完成。

我通过一个小改动运行你的程序:我添加了一个等待主线程死的线程,然后打印一条消息:

public class ProducerConsumerProblem
{
    static volatile Thread mainThread;
    public static void main(String[] args)
    {
        mainThread = Thread.currentThread();
        ProducerConsumerStack st = new ProducerConsumerStack();
        new ProducerThread(st);
        new ConsumerThread(st);

        new Thread(() -> {
            try {
                mainThread.join();
            } catch (Exception ex) {
                System.out.println("Aaaaaaaugh!");
            }
            System.out.println("Nighty Night!");
        }).start();

    }
}

它打印了“Nighty Night!”,证明主线程确实实际上死了。

未终止的线程是消费者线程:当生产者线程调用st.push()十五次时,消费者线程只完成了对st.pop()的五次调用,并且它被卡在了第六个电话,等待一个永远不会发生的通知。

您可能希望查看ProducerConsumerStack课程。你把“堆栈”放在它的名字中,但它对我来说看起来不像堆栈。首先,堆栈应该能够存储多个项目。你的只能存储一个。