did*_*xga 0 java stack deadlock
以下代码的目的是像堆栈一样实现LIFO容器,而在检索元素时,它将检查列表中是否存在任何现有元素,或者它是否保留在检索元素的线程上,直到有新元素为止元素被插入.
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();
}
}
Run Code Online (Sandbox Code Playgroud)
}
但是每当调用pop()时List中没有元素,就会发生死锁.如何在避免数据死锁的同时修改此类以实现初始目的.谢谢
关于这门课我会改变很多东西很难知道从哪里开始.这个最简单的解决方案是删除synchronized(list)块,因为这些块是冗余的,只会导致问题,如您所见.
另一种解决方案是使用内置于Java的Stack类.您的类可能会因为它具有相同的名称而与构建的类混淆.
或者我会使用LinkedBlockingDeque作为我的集合是线程安全的,并且有pop()和push()方法.
编辑:如果你想知道为什么你得到一个死锁,这是因为你持有两个锁(一个在堆栈上,另一个在LinkedList上)但你只释放一个锁与你的wait()(一个在堆栈上)意味着没有其他线程可以获得列表上的锁定.无法一次对两个对象进行wait().
你的代码与此大致相同(可能更清晰)
public void push(Object x) {
synchronized(this) {
synchronized (list) { // cannot get a lock on `list` while pop() is called.
list.addLast(x);
this.notify();
}
}
}
public Object pop() throws Exception {
synchronized(this) {
synchronized (list) {
if (list.size() <= 0) {
this.wait(); // releases the lock on `this`, but keep the lock on `list`
}
return list.removeLast();
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1112 次 |
| 最近记录: |