日期:2014-05-20  浏览次数:20884 次

线程通信异常
[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