我使用堆栈作为我的存储来实现我的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);
}
}
答案 0 :(得分: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();
}
}}
}}
答案 1 :(得分: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();
}
}}
}
}