I created a stack class like this. Some times it runs and sometimes it will through ArrayIndexOutofBoundException. What’s wrong in threading? Couldn’t understand please help.
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();
}
}
You set
in the constructor of
StackImpl, yet your isEmpty method checks for 0:So the while loop will fall through on first pop, if the pusher hasn’t added any values yet:
Set thetopOfStackto 0 on the constructor and it should work.Edit: come to think of it, instead change the
isEmpty-method toreturn topOfStack < 0;, and leave thetopOfStack = -1;in your constructor… otherwise element in index 0 is never popped.