线程化ArrayIndexOutofBoundException

时间:2012-01-29 12:56:38

标签: java multithreading generics

我创建了一个像这样的堆栈类。有时会运行,有时会通过ArrayIndexOutofBoundException。线程有什么问题?无法理解请帮助。

public class StackImpl<E> implements Stack<E>{

private E[] stackArray;

private int topOfStack;

public StackImpl(int size) {
    stackArray = (E[]) new Object[size];
    topOfStack = -1;
}

public synchronized void push(E e) {
    while (isFull()) {
        try {
            System.out.println("stack is full cannot add " + e);
            wait();
        } catch (InterruptedException exception) {
            exception.printStackTrace();
        }
    }
    stackArray[++topOfStack] = e;
    System.out
            .println(Thread.currentThread() + " :notifying after pushing");
    notify();
}

public boolean isEmpty() {
    return topOfStack == 0;
}

public synchronized E pop() {
    while (isEmpty()) {
        try {
            System.out.println("stack is empty cannot pop ");
            wait();
        } catch (InterruptedException e) {

        }
    }
    System.out.println(topOfStack);
    E element = stackArray[topOfStack];
    stackArray[topOfStack--] = null;
    System.out.println(Thread.currentThread() + " notifying after popping");
    notify();
    return element;
}

public boolean isFull() {
    return topOfStack >= stackArray.length-1;
}

public static void main(String[] args) {
    final Stack<Integer> stack = new StackImpl<Integer>(10);
    (new Thread("Pusher") {
        public void run() {
            while (true) {
                stack.push(10);
            }
        }
    }).start();
    (new Thread("Popper") {
        public void run() {
            while (true) {
                stack.pop();
            }
        }
    }).start();
}

}

1 个答案:

答案 0 :(得分:5)

你设置

topOfStack = -1;

StackImpl的构造函数中,但你的isEmpty方法检查0:

public boolean isEmpty() {
    return topOfStack == 0;
}

因此,如果推送器尚未添加任何值,则while循环将在第一个pop中出现:

    public synchronized E pop() {
        while (isEmpty()) {
            try {
                System.out.println("stack is empty cannot pop ");
                wait();
            } catch (InterruptedException e) {

            }
        }

在构造函数上将topOfStack设置为0,它应该可以正常工作。

编辑:开始考虑它,而是将isEmpty - 方法更改为return topOfStack < 0;,并将topOfStack = -1;保留在构造函数中...否则索引0中的元素永远不会弹出