나는 훈련 목적으로 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;
}
}
내 질문은 다음과 같습니다
그것을 확인
isEmtpy()
방법을 동기화하지가가? 그것은 다른 스레드가 스택을 동시에 수정하는 경우에도 일관된 결과를 반환하기 때문입니다 (초기 또는 최종가 아닌 isEmpty 상태로 들어갈 작업이 없습니다). 아니면 동기화 된 객체의 모든 메소드를 동기화하는 것이 더 나은 설계입니까?나는
forcePop()
메소드를 좋아하지 않습니다. 요소를 팝업하기 전에 항목이 스택으로 푸시 될 때까지 기다릴 수있는 스레드를 만들고 싶습니다. 스레드의run()
메서드에서wait()
루프를 수행하는 것이 가장 좋은 방법이라고 생각했지만 그것이IllegalMonitorStatException
을 던지기 때문에. 이런 식으로하는 적절한 방법은 무엇입니까?다른 의견이나 제안이 있으십니까?
고맙습니다!
메서드를 잠그지 말고, 개체를 잠그는 것을 선호하십시오. 읽어보기 : http://download.oracle.com/javase/tutorial/essential/concurrency/locksync.html –
스택은 이미 동기화 된 벡터를 확장합니다. 컬렉션의 다른 선택이 훈련 연습을 위해 더 좋을 수도 있습니다. –
Don Roby : 예, axtavt가 지적한대로 ArrayDeque를 사용하고 있습니다. – nbarraille