我在"Add“和"Get”方法中有一个带有阻塞机制的队列,其中第一个线程添加数据,第二个线程获取数据。
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();
}
}
}在上面的代码中,如果第一个线程试图获取数据,而队列是空的,则我通过等待(0)输入等待,直到其他线程添加数据来排队等待data ()的发布。
现在,当队列已满时,我想添加另一个“锁”,并且有人试图向队列中添加更多数据:
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;
}发布于 2011-12-15 12:35:02
为什么有三条synchronized语句?wait(0)只释放this上的锁,所以只需保留该锁并从方法和synchronized(myLock)中转储synchronized。
每当您调用某个对象(在本例中是对this的调用)时,该对象上的锁将自动释放,以允许其他线程继续执行。但是您永远不会调用myLock (而且您也不应该这样做,因为您已经在调用this )。该部分是多余的,并导致死锁。
考虑一下这个场景:应该添加的线程接受myLock上的锁,但发现队列已满,所以它等待。此等待不会释放myLock上的锁。另一个线程希望获取数据,但不能进入synchronized块,因为第一个线程没有释放myLock上的锁。
结论:去除synchronized(myLock)阻滞。
发布于 2011-12-15 11:45:08
为什么你不看看java.util.BlockingQueue。在你的情况下它可能是有用的。
特别是看看java.util.LinkedBlockingQueue,如果在构造函数中指定队列的容量,那么队列就会阻塞。
发布于 2011-12-15 11:47:07
从方法签名中删除synchronized关键字,因为这意味着您持有整个方法调用的this监视器-- synchronized(this)块只是多余的。
编辑:
...Then在myLock上调用、等待和通知,而不是this。完全忘记在this上同步的问题。这是因为在等待(当前代码中的this )时,没有释放myLock锁,因此其他线程无法到达notify()。
https://stackoverflow.com/questions/8519529
复制相似问题