这可能是一个新手问题 - 我在使用BlockedLinkedQueue时遇到了死锁情况 - 这是我的代码剪辑:
public class mytest {
private BlockedLinkedQueue myQueue;
public synchronized void consumer() {
...
myQueue.take()
...
}
public synchronized void producer() {
...
myQueue.put()
...
}
}
Run Code Online (Sandbox Code Playgroud)
我注意到有时候我遇到了僵局.许多producer()线程正在方法监视器上等待,并且一个使用者在take()上被阻塞.这是预期的吗?我知道我不需要同步BLockedLinkedQUeue - 但我有很多其他对象,我需要同步这些方法..
小智 8
是的,预计会出现这种僵局.使用空队列调用consumer()时会发生这种情况.在这种情况下,consumer()保持锁定"this"并等待myQueue中的对象.同一时间,任何producer()都不能锁定"this"(由消费者持有),因此不能将任何对象放到myQueue上,这会阻止消费者获取对象.
要解决死锁,您可以只使部分方法同步或使用简单队列并实现自己的等待数据.部分同步的示例:
public class mytest {
private BlockedLinkedQueue myQueue;
public void consumer() {
synchronized(this) {
...
}
myQueue.take();
synchronized (this) {
...
}
}
public void producer() {
synchronized(this) {
...
}
myQueue.put()
synchronized(this) {
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,在myQueue操作期间释放锁定"this".并且它将允许producer()以它的方式进行并将对象放入队列.
第二个例子:
public class mytest {
private Queue myQueue;
public synchronized void consumer() {
...
while (myQueue.isEmpty()) {
this.wait();
}
myQueue.take()
...
}
public synchronized void producer() {
...
myQueue.put()
this.notify();
...
}
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,在调用this.wait()期间释放对"this"的锁定(有关详细信息,请参阅Object.wait()),它允许生产者将对象放入队列.此外,生产者唤醒了一个等待数据的消费者.
请注意,在两种情况下,只执行"half"消费者方法时,将执行生产者方法.即消费者方法根本不是原子的,而只是它的一半.如果你需要消费者的原子性,那么你应该考虑更好地规范生产者/消费者方法,因为所描述的死锁是"同步"中的逻辑缺陷.在执行"atomic"consumer()方法时不能放置对象,同时consumer()要求对象在队列中.
| 归档时间: |
|
| 查看次数: |
1494 次 |
| 最近记录: |