请帮帮我。这段代码可能会被阻止在哪里? 我认为它不应该阻止。 getItem等待的线程, 详细信息显示在存储中,如果从存储中获取任何项目,则通知任何人。 putItem notfiy的线程,何时 它将任何细节放入存储中并等待它已满。这样对吗? 我认为不,因为死锁出现了 抱歉我的英语。这不是我的母语。
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;
}
}
答案 0 :(得分:2)
在putItem
和getItem
您正在同步两个不同的对象,expectPlaceObject
和expectItemObject
。
问题是您在两种方法中以不同的顺序同步它们。可能发生的事情如下:
putItem
并锁定expectedItemObject
getItem
并锁定expectedPlaceObject
调查死锁的一个好方法是使用jstack来获取进程的线程转储。输出将列出您的死锁。
答案 1 :(得分:1)
尝试使用以下方法更改getSize()方法:
public Integer getSize() {
return details.size();
}