【发布时间】:2015-05-18 14:24:18
【问题描述】:
请帮助我。此代码可能会在哪里被阻止? 我认为它不应该阻塞。线程,getItem 等待, 详细信息出现在存储中,如果它从存储中获取任何项目,则通知任何人。 putItem 通知的线程,当 它将任何细节放入存储中,并等待它是否已满。这样对吗? 我认为没有,因为出现了僵局 对不起我的英语。这不是我的母语。
public class Storage<E> {
ArrayList<E> details;
private Integer limit; //Storage Capacity
final MonitorObject expectItemObject; //objects for synchronization
final MonitorObject expectPlaceObject;
public Storage(Integer limit)
{
this.limit = limit;
expectItemObject = new MonitorObject();
expectPlaceObject = new MonitorObject();
details = new ArrayList<>(limit);
}
public Integer getSize()
{
int detNo=0;
synchronized (expectPlaceObject)
{
synchronized (expectItemObject) {
detNo = details.size();
}
}
return detNo;
}
public void putItem(E e) throws InterruptedException
{
synchronized (expectPlaceObject)
{
while (getSize().equals(limit)) { //ensure that we have a place
expectPlaceObject.wait(); //sleep if storage is full
}
synchronized (expectItemObject) { //there is no trouble in inners synchronized, as the second is not blocking.
details.add(e);
expectItemObject.notify(); //if anybody,who expect item, sleep, awake him.
}
}
}
public E getItem() throws InterruptedException
{
E detail;
synchronized (expectItemObject)
{
while (getSize() == 0) {
expectItemObject.wait(); //sleep if storage is empty
}
synchronized (expectPlaceObject) {
detail= details.remove(0);
expectPlaceObject.notify(); //if anybody,who expect place sleep, awake him.
}
}
return detail;
}
}
【问题讨论】:
-
旁注:一个症结在于锁定;人类非常不善于预测会发生什么。我阅读了您的代码并检查了“他是否总是以相同的顺序请求锁定”......并且忽略了您正在这样做。有时这些事情真的很容易,但很多时候并非如此。然后创建一个 java 转储并分析它会快得多。所以我的建议是:学习如何做到这一点;它可以在未来为您节省大量时间。
标签: java deadlock synchronized