0

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

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 class MyArrayStack implements 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);
}
}
4

2 回答 2

1

哦 。我有问题,您正在对此进行同步,而不是在堆栈对象上进行同步,例如synchronized(mStack){

然后等待并通知这个对象。

添加代码为您提供帮助。我已将堆栈更改为在我的代码中列出,因为我没有您的堆栈对象。

private static 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();
                    } catch(Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            mNumber++;
            System.out.println("Producer generates number:" + mNumber);
            mStack.add(mNumber);
            mStack.notify();
            }
        }   
    }
}

private static 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();
                    } catch(Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            int number = mStack.remove(0);
            System.out.println("Consumer consumes number:" + number);
            mStack.notify();
            }
        }}

}}
于 2013-05-09T07:15:41.897 回答
1

要解决您的问题,您应该synchronize打电话wait()notifyAll()mStack和不开this。通过this在您中使用,您Producer正在等待生产者对象,而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();
                }
            }}

    }
}
于 2013-05-09T07:28:31.923 回答