【发布时间】:2011-02-02 16:09:03
【问题描述】:
我用 Java 制作了一个简单的同步 Stack 对象,仅用于培训目的。 这是我所做的:
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。做这种事情的正确方法是什么?还有其他意见/建议吗?
谢谢!
【问题讨论】:
-
不要锁定方法,更喜欢锁定对象。阅读:download.oracle.com/javase/tutorial/essential/concurrency/…
-
堆栈扩展了已经同步的 Vector。对于这个训练练习,不同的收集选择可能会更好。
-
Don Roby:是的,正如 axtavt 所指出的,我现在正在使用 ArrayDeque。
-
肖恩·帕特里克·弗洛伊德:所以你说这样做更好:public void pop(){synchronized(this.stack){return this.stack.pop();}} 比这样:public void synchronized pop(){return this.stack.pop();} ?
标签: java multithreading synchronization