The purpose of the following code is to implement a LIFO container just like a Stack, while, when retrieve an element, it will check if there is any existing element in the list, or it hold on thread that retrieving element until there is a new element get inserted.
public class Stack {
LinkedList list = new LinkedList();
public synchronized void push(Object x) {
synchronized (list) {
list.addLast(x);
notify();
}
}
public synchronized Object pop() throws Exception {
synchronized (list) {
if (list.size() <= 0) {
wait();
}
return list.removeLast();
}
}
}
but deadlock may occur whenever call pop() where there is no element in the List. How to amend this Class to achieve the initial purpose while avoiding pontential deadlock. Thanks
There are so many things I would change about this class its hard to know where to start. This simplest solution is to remove the
synchronized(list)blocks as these are redundant and just cause problems as you can see.Another solution would be to use the Stack class which is builtin to Java. Your class could be confused for the built one as it has the same name.
Or I would use a LinkedBlockingDeque which is thread safe as my collection and has pop() and push() methods.
EDIT: If you want to know why you are getting a dead lock, it is because you are holding two locks (one on the Stack, the other on the LinkedList) but you are releasing only one lock with your wait() (the one on the Stack) meaning no other thread can get the lock on the list. There is no way to wait() on two objects at once.
Your code is much the same as this (which might be clearer)