我对多线程知识很差。
我期望下面的程序能够完美运行,但是它无法正常工作,并且会在Exception以下产生。
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at com.onmobile.client.D.callD(Deadlock.java:76)
at com.onmobile.client.B.run(Deadlock.java:50)
at java.lang.Thread.run(Unknown Source)
Java文件
public class Deadlock {
C c = new C();
D d = new D();
public static void main(String[] args) {
new Deadlock();
}
public Deadlock() {
A a = new A(d,c);
B b = new B(d,c);
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
t1.start();
t2.start();
}
}
class A implements Runnable{
D dObj;
C cObj;
A(D obj, C obj1){
this.dObj = obj;
this.cObj = obj1;
}
@Override
public void run() {
cObj.callC(dObj);
}
}
class B implements Runnable{
D dObj;
C cObj;
B(D obj, C obj1){
this.dObj = obj;
this.cObj = obj1;
}
@Override
public void run() {
dObj.callD(cObj);
}
}
class C{
public synchronized void callC(D dObj){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
dObj.callD1();
}
public synchronized void callC1(){
}
}
class D{
public synchronized void callD(C cObj){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
cObj.callC1();
cObj.notify();
}
public synchronized void callD1(){
}
}
我认为在callC()方法内部,类C的对象即cObj进入等待状态,同时控制将转到callD()方法,并在那里调用cObj.notify();。
因此,这将唤醒在对象cObj上等待的等待线程。
但这给了我例外。
我认为解决我的问题的方法可以是:
Java: IllegalMonitorStateException on notify()
但我对它的理解不正确。
请指导我哪里出问题了。
最佳答案
如果要通知或等待对象,则线程必须拥有您要操作的对象的监视器。
public synchronized void callD(C cObj){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
cObj.callC1();
cObj.notify();
}
在此代码部分中,您将在类
D
的实例上进行同步,因为已同步的方法始终会获取其“活动”对象的监视器。但是要使用cObj.notify()
,您必须获取cObj
实例的监视器,例如通过做synchronized(cObj) {
cObj.notify();
}