我使用堆栈作为存储来实现我的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();
}
}}
}
}
但是,当我测试该程序时,似乎只有生产者可以使用,它会不断生成数字,而使用者线程似乎无法使用。
专家可以帮助我调试代码中哪里出错了吗?谢谢。
编辑:我的堆栈代码是:
公共类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);
}
}
最佳答案
要解决您的问题,您应该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();
}
}}
}
}