And*_*ich 36 java multithreading locking pool
为什么会这样?问题是监视器对象肯定不是null,但我们仍然经常得到这个异常:
java.lang.IllegalMonitorStateException: (m=null) Failed to get monitor for (tIdx=60)
at java.lang.Object.wait(Object.java:474)
at ...
Run Code Online (Sandbox Code Playgroud)
引发这种情况的代码是一个简单的池解决方案:
public Object takeObject() {
Object obj = internalTakeObject();
while (obj == null) {
try {
available.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
obj = internalTakeObject();
}
return obj;
}
private Object internalTakeObject() {
Object obj = null;
synchronized (available) {
if (available.size() > 0) {
obj = available.keySet().iterator().next();
available.remove(obj);
synchronized (taken) {
taken.put(obj, Boolean.valueOf(true));
}
}
}
return obj;
}
public void returnObject(Object obj) {
synchronized (taken) {
taken.remove(obj);
}
synchronized (available) {
if (available.size() < size) {
available.put(obj, Boolean.valueOf(true));
available.notify();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我错过了什么吗?
编辑:异常发生available.wait();在行.
tgd*_*ies 72
请参阅Object.wait的javadoc.
特别是"当前线程必须拥有此对象的监视器".和"[throws] IllegalMonitorStateException - 如果当前线程不是对象监视器的所有者." 也就是说,您需要在要调用的对象上进行同步等待.
所以你的代码应该是:
synchronized (available) {
available.wait();
}
Run Code Online (Sandbox Code Playgroud)