Я создал простой синхронизированный объект Stack на Java, просто для обучения. Вот что я сделал:
public class SynchronizedStack {
private ArrayDeque<Integer> stack;
public SynchronizedStack(){
this.stack = new ArrayDeque<Integer>();
}
public synchronized Integer pop(){
return this.stack.pop();
}
public synchronized int forcePop(){
while(isEmpty()){
System.out.println(" Stack is empty");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return this.stack.pop();
}
public synchronized void push(int i){
this.stack.push(i);
notifyAll();
}
public boolean isEmpty(){
return this.stack.isEmpty();
}
public synchronized void pushAll(int[] d){
for(int i = 0; i < d.length; i++){
this.stack.push(i);
}
notifyAll();
}
public synchronized String toString(){
String s = "[";
Iterator<Integer> it = this.stack.iterator();
while(it.hasNext()){
s += it.next() + ", ";
}
s += "]";
return s;
}
}
Вот мои вопросы:
Можно ли не синхронизировать метод isEmtpy ()
? Я полагал, что это потому, что даже если другой поток одновременно изменяет стек, он все равно будет возвращать согласованный результат (нет операции, которая переходит в состояние isEmpty, которое не является ни начальным, ни окончательным). Или лучше всего синхронизировать все методы синхронизированного объекта?
Мне не нравится метод forcePop ()
. Я просто хотел создать поток, который мог бы ждать, пока элемент будет помещен в стек, прежде чем вставлять элемент, и я подумал, что лучшим вариантом было бы выполнить цикл с помощью wait ()
в run ()
потока, но я не могу, потому что он вызывает исключение IllegalMonitorStatException
. Каков правильный способ сделать что-то подобное?
Любой другой комментарий / предложение?
Спасибо!