当前位置: 代码迷 >> J2SE >> 线程通信错误
  详细解决方案

线程通信错误

热度:79   发布时间:2016-04-24 01:15:10.0
线程通信异常
[code=Java][/code]

package cn.itcast;

public class ThreadCommunication {


public static boolean bool =true;
public static void main(String[] args) {
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<20;i++){
synchronized (this.getClass()) {
while(!bool){
for(int j=0;j<10;j++){
System.out.println("thread:"+Thread.currentThread()+"----"+j+"----"+i);
}
bool=true;
this.notify();
}
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
thread.start();
for(int j=0;j<20;j++){
synchronized(thread.getClass()){
while(bool){
for(int i=0;i<10;i++){
System.out.println("main:"+Thread.currentThread()+"----"+i+"----"+j);
}
bool=false;
thread.notify();
}
try {
thread.wait();
} catch (InterruptedException e) {
System.out.println("hh");
e.printStackTrace();
}
}
}
}

}
运行时出现异常:

Exception in thread "main" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at cn.itcast.ThreadCommunication.main(ThreadCommunication.java:37)
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at cn.itcast.ThreadCommunication$1.run(ThreadCommunication.java:21)
at java.lang.Thread.run(Unknown Source)
求解!

------解决方案--------------------
Thread thread=new Thread(new Runnable()) 少了一个括号。。。

------解决方案--------------------
没看具体逻辑,但是说两点:
1、wait和notify必须在同步方法或者同步代码块中调用,这点你搞对了
2、当前线程(执行wait或者notify或notifyAll的线程)必须是这个对象的锁的持有者,必须你调用的方式是:
xxx.wait(),那么你同步的就必须是xxx,就楼主的例子:因为你同步的是xxx.getClass()这个对象,那么就应该用xxx.getClass().wait()这种方式,或者改为synchronized(xxx),然后xxx.wait(),对于notify,notifyAll也是一样的改法。
------解决方案--------------------
错误信息表示notify不是在synchronized方法或synchronized块中调用的
------解决方案--------------------
我觉得有两个问题:
1 同步的对象不一致.
thread线程里synchronized (this.getClass()) ,这个同步对象是匿名类的一个Class对象。这个匿名类是ThreadCommunication$1.而调用nonify()和wait()的是this. 这个this 是匿名类”ThreadCommunication$1“的对象。
在main线程里,synchronized(thread.getClass()),这个同步对象是一个ThreadL类的Class对象,与thread线程用的显然不一样。

建议用一个其他对象作同步对象。比如:static Object forLock=new Object();

2 最后执行完循环的线程(本程序是thread)没有唤醒机会,程序不能正常退出。
建议while里先等待,后运行。
试着改了一下,供参考:
Java code
/* ThreadCommunication1.java */package cn.itcast;public class ThreadCommunication1{    public static Object forLock=new Object();        public static boolean bool =true;    public static void main(String[] args)           {        Thread thread=new Thread(new Runnable()        {            @Override            public void run()             {                for(int i=0;i<20;i++)                {                    //ThreadCommunication1.forLock=this.getClass();                    synchronized (ThreadCommunication1.forLock)                           {                        while(bool)                        {                            try                                   {                                ThreadCommunication1.forLock.wait();                            }                                   catch (InterruptedException e)                             {                                e.printStackTrace();                            }                        }                            for(int j=0;j<10;j++)                            {                                System.out.println("thread:"+Thread.currentThread()+                                    "----"+j+"----"+i);                            }                            bool=true;                            ThreadCommunication1.forLock.notify();                    }                }            }        });        thread.start();        for(int j=0;j<20;j++)        {            synchronized(ThreadCommunication1.forLock)            {                while(!bool)                {                    try                     {                        ThreadCommunication1.forLock.wait();                    }                           catch (InterruptedException e)                           {                        System.out.println("hh");                        e.printStackTrace();                    }                }                for(int i=0;i<10;i++)                {                    System.out.println("main:"+Thread.currentThread()+"----"+i+"----"+j);                }                bool=false;                ThreadCommunication1.forLock.notify();            }        }    }//end main}//end class
  相关解决方案