我有一个队列,在“添加”和“获取”方法中有一些阻塞机制,其中第一个线程添加数据,第二个线程获取数据。
public synchronized MyObj getData() {
synchronized (myLock) {
synchronized (this) {
if (isEmpty()) {
wait(0);
}
}
return getData();
}
}
public synchronized void addData(MyObj data) {
if (!isFull()) {
putData(data);
synchronized (this) {
notify();
}
}
}
在上面的代码中,如果第一个线程尝试获取数据并且队列为空,我会通过 wait(0) 进入等待状态,直到其他线程将数据添加到队列中,然后通过 notify() 释放等待状态。
现在我想在队列已满并且有人试图向其中添加更多数据时添加另一个“锁”:
public synchronized MyObj getData() {
synchronized (myLock) {
synchronized (this) {
if (isEmpty()) {
wait(0);
}
}
synchronized (this) {
notify();
}
return getData();
}
}
public synchronized void addData(MyObj data) {
synchronized (myLock) {
synchronized (this) {
if (isFull()) {
wait(0);
}
}
}
synchronized (this) {
notify();
}
PutData(data);
}
结果不是我所期望的,我猜我遇到了死锁,因为进程被卡住了。
更新
这是我获取数据的方式:
queueSize--;
startPointer = (startPointer + 1) % mqueueSize;
data = (String) queue[startPointer];
这是我添加数据的方式
queueSize++;
endPointer = (endPointer + 1) % mqueueSize;
queue[endPointer] = data;
public synchronized boolean isEmpty() {
return queueSize== 0;
}
public synchronized boolean isFull() {
return queueSize== mqueueSize;
}
最佳答案
为什么你有三个synchronized
语句? wait(0)
只释放 this
上的锁,所以只保留那个锁并从方法和 中转储
。synchronized
同步(myLock)
每当您在某个对象上调用 wait(在本例中您正在调用 this
)时,该对象上的锁将自动释放以允许其他线程继续进行。但是你永远不会在 myLock
上调用等待(你也不应该,因为你已经在调用 this
了)。那部分是多余的,会导致死锁。
考虑这种情况:应该添加的线程获取了 myLock
上的锁,但发现队列已满,因此它等待。此等待不会释放 myLock
上的锁。另一个线程想要取数据但是不能进入synchronized
block ,因为第一个线程没有释放myLock
上的锁。
结论:移除synchronized(myLock)
block 。
关于java - 等待/通知死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8519529/