java - Java 中使用堆栈的生产者-消费者

标签 java multithreading concurrency producer-consumer

我使用堆栈作为存储来实现我的生产者-消费者模型。

public class Main {

/**
 * @param args
 */
public static void main(String[] args) {
    Stackable<Integer> stack = new MyArrayStack<Integer>();
    Producer producer = new Producer(stack);
    Consumer consumer = new Consumer(stack);
    producer.start();
    consumer.start();
}

private static class Producer extends Thread {
    public Producer(Stackable<Integer> s) {
        mStack = s;
    }

    private Stackable<Integer> mStack = null;
    private int mNumber = 0;

    @Override
    public void run() {
        // TODO generates number here
        while(true){        synchronized(this){
                while(!mStack.isEmpty())
                {
                    try{
                        this.wait();
                    } catch(Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            mNumber++;
            System.out.println("Producer generates number:" + mNumber);
            mStack.push(mNumber);
            this.notifyAll();
            }
        }   
    }
}

private static class Consumer extends Thread {
    public Consumer(Stackable<Integer> s) {
        mStack = s;
    }

    private Stackable<Integer> mStack = null;

    @Override
    public void run() {
        // TODO consume number here.
        while(true){
            synchronized(this){
                while(mStack.isEmpty())
                {
                    try{
                        this.wait();
                    } catch(Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            int number = mStack.pop();
            System.out.println("Consumer consumes number:" + number);
            this.notifyAll();
            }
        }}

}

}

但是,当我测试程序时,似乎只有生产者可以工作,它不断生成数字,而消费者线程似乎不工作。

专家可以帮我调试代码中出错的地方吗?谢谢。

编辑:我的堆栈代码是: 公共(public)类 MyArrayStack 实现 Stackable {

private static final int DEFAULT_SIZE = 16;
protected int sp; // empty stack
protected E[] head; // array
private int size;
private int count;

MyArrayStack(int size) {
    if (size <= 0)
          throw new IllegalArgumentException(
                     "Stack's capacity must be positive");
    head = (E[])new Object[size];
    sp = -1;
    count=0;

}






public boolean isFull() {
    return sp == this.size -1;
}

@Override
public void push(Object e) {

    if (!isFull())
    {
        head[++sp] = (E) e;
        count++;
    }

}

@Override
public E pick() {
    if (sp == -1)
        try {
            throw new Exception("Stack is empty");
        } catch (Exception e) {

            e.printStackTrace();
        }
    return head[sp];
}

@Override
public E pop() {
    count--;
    if (isEmpty()) {
        return null;
    } else
        return head[sp--];

}

@Override
public int count() {

    return count;
}

@Override
public boolean isEmpty() {

    return (sp == -1);
}
}

最佳答案

要解决您的问题,您应该在 mStack同步并调用wait()notifyAll(),不是这个。通过在您的Producer中使用this,您正在等待生产者对象,而在Consumer中,您正在等待消费者对象,这是不正确的。因此,您必须对同一个对象调用 wait() 以及 notifyAll(),在您的情况下应该是 mStack

这是运行良好的代码片段:

package com.thread.concurrency;

import java.util.LinkedList;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        Main mainObj = new Main();
        List<Integer> stack = new LinkedList<Integer>();
        Producer producer = mainObj.new Producer(stack);
        Consumer consumer = mainObj.new Consumer(stack);
        producer.start();
        consumer.start();
    }

    private class Producer extends Thread {
        public Producer(List<Integer> s) {
            mStack = s;
        }

        private List<Integer> mStack = null;
        private int mNumber = 0;

        @Override
        public void run() {
            // TODO generates number here
            while (true) {
                synchronized (mStack) {
                    while(!mStack.isEmpty())
                    {
                        try{
                            mStack.wait(); // this.wait();
                        } catch(Exception e)
                        {
                            e.printStackTrace();
                        }
                    }
                mNumber++;
                System.out.println("Producer generates number:" + mNumber);
                mStack.add(mNumber);
                    mStack.notifyAll();// this.notifyAll();
                }
            }   
        }
    }

    private class Consumer extends Thread {
        public Consumer(List<Integer> s) {
            mStack = s;
        }

        private List<Integer> mStack = null;

        @Override
        public void run() {
            // TODO consume number here.
            while(true){
                synchronized (mStack) {
                    while(mStack.isEmpty())
                    {
                        try{
                            mStack.wait(); // this.wait();
                        } catch(Exception e)
                        {
                            e.printStackTrace();
                        }
                    }
                int number = ((LinkedList<Integer>) mStack).removeLast();
                System.out.println("Consumer consumes number:" + number);
                    mStack.notifyAll();// this.notifyAll();
                }
            }}

    }
}

关于java - Java 中使用堆栈的生产者-消费者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16456121/

相关文章:

c# - BackgroundWorker 返回到错误的线程

c# - ConcurrentBag<T> 和 lock(List<T>) 添加或删除哪个更快?

java - Java Concurrency In Practice 中的 CountDownLatch 示例

java - AJAX 调用未到达 Spring MVC Controller

java - JFrame 中的 LWJGL 显示在 OSX 上性能较差

java - 将数据保存在 vector 中并在其他函数中重用

c++ - 多线程C++ dll全局变量导致崩溃

java - 即使所有的latch.countdown()都被调用,程序仍继续执行

java - 收到的 JMS 消息被截断

go - 同时多次下载同一文件