私は、トレーニング目的のために、Javaでシンプルに同期化されたStackオブジェクトを作成しました。ここ は私がやったことです:ここではSynchronizedStackクラスを正しく作成する方法は?
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;
}
}
は私の質問です:
はそれがOK
isEmtpy()
メソッドを同期させることはありませんか?なぜなら、別のスレッドが同時にスタックを修正していても、それはまだ一貫性のある結果を返すからです(初期または最終ではないisEmpty状態になる操作はありません)。それとも、同期化されたオブジェクトのすべてのメソッドを同期させるのが良い設計ですか?私は
forcePop()
メソッドが嫌いです。要素をポップする前に項目がスタックにプッシュされるまで待つことができたスレッドを作成したかったので、スレッドのrun()
メソッドでwait()
のループを実行するのが最善の選択肢だと思っていましたが、それはIllegalMonitorStatException
を投げるからです。このようなことをする正しい方法は何ですか?他のコメント/ご提案ですか?
ありがとうございます!
メソッドをロックしたり、オブジェクトをロックしたりしないでください。 –
スタックは、既に同期されているベクトルを拡張します。このトレーニングの練習には、コレクションの選択肢が異なる方がよいでしょう。 –
Don Roby:axtavtが指摘しているように、ArrayDequeを使用しています。 – nbarraille