我在“添加”和“获取”方法中有一个带有某些阻止机制的队列,其中第一个线程添加数据,第二个线程获取数据。
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
中转储synchronized(myLock)
即可。
每当您在某个对象上调用wait(在这种情况下,您是在this
上调用)时,该对象上的锁都会自动释放,以允许其他线程继续执行。但是,您永远不要在myLock
上调用wait(也不应该,因为您已经在this
上调用)。该部分是多余的,并导致死锁。
考虑这种情况:本应添加的线程在myLock
上获得了锁定,但发现队列已满,因此等待。此等待不会释放对myLock
的锁定。另一个线程想要获取数据,但不能进入synchronized
块,因为第一个线程没有释放对myLock
的锁定。
结论:删除synchronized(myLock)
块。