public class Test {
static Thread laurel,hardy;
public static void main(String[] args) {
laurel=new Thread(){
public void run(){
try {
hardy.sleep(1000);
} catch (InterruptedException e) {
System.out.println("b");
}
System.out.println("c");
}
};
hardy=new Thread(){
public void run(){
System.out.println("d");
try {
laurel.wait();
} catch (InterruptedException e) {
System.out.println("e");
}
System.out.println("f");
}
};
laurel.start();
hardy.start();
}
}    第一眼看到这个代码,我感觉hardy.sleep(1000);这边运行肯定会出错,因为hardy可能为null,可惜不是这么回事。由于sleep()是一个静态方法,它影响的是当前线程,也就是laurel(即使对hardy调用也一样),这容易让人误解,但却合法。
    理解了上面一点,你就会发现这段代码的问题所在,hardy尝试调用laurel.wait(),这时会发生IllegalMonitorStateException。(wait()不是静态方法)。有兴趣的可以将static Thread laurel,hardy;这段定义放入main()中改为Thread laurel,hardy;猜猜会发生什么......如果我解释的有问题的话,请高手指点下

解决方案 »

  1.   


    1.你的这种写法就不准确,sleep是类方法.本就应该由类来调用.你写成一个对象实例,但是实际根本不用它try {
        hardy.sleep(1000);
    } catch (InterruptedException e) {
        System.out.println("b");
    }2.wait()出错,和是不是静态方法也没有本质联系.
    你去查一下 IllegalMonitorStateException 是什么意思.静态方法最好还是叫做类方法.类方法,对象方法,更便于理解本质.
      

  2.   

    hardy.sleep(1000);
     这段话在Eclipse等IDE环境中会提示警告的因为它会被编译器修改为Thread.sleep(1000),也就是你前面写哪个Thread对象都一样的,没有区别。所以也不可能出现NullPointerException的问题
      

  3.   

    通常没人会写出这代码,但面试题和考证书的时候会有这种题目。我注明wait不是静态方法是针对于sleep而言的这段代码抛异常是因为laurel已经调用了sleep(),而hardy中又调用了laurel.wait();所以抛异常。对于抛出的异常我也不不是太明白,抛出的是运行期异常,而非catch中的InterruptedException。
    Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:485)
    at Test$2.run(Test.java:20)
    非常感谢你的关注......
      

  4.   

    以前一直都没关注过“Eclipse等IDE环境中会提示警告”,通常我会忽略警告的,学习了...
      

  5.   

    以前一直都没关注过“Eclipse等IDE环境中会提示警告”,通常我会忽略警告的,学习了...你太有才,不用ide开发java的程序员不是好的程序员
      

  6.   

    我用Myeclipse,不过我确实很少关注其中Line Number左边是否黄色的三角,只要没红色就OK了
      

  7.   


    你把
            hardy=new Thread(){
                public void run(){
                    System.out.println("d");
                    try {
                        laurel.wait();
                    } catch (InterruptedException e) {
                        System.out.println("e");
                    }
                    System.out.println("f");
                }
            };改为:
            hardy=new Thread(){
                public void run(){
                    System.out.println("d");
                    try {
                        synchronized(laurel) {
                            laurel.wait();
                        }
                        
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        System.out.println("e");
                    }
                    System.out.println("f");
                }
            };跑一下.注意wait方法调用石油条件的.
      

  8.   

    不管你这个类是否是  线程类, wait方法都可用, 但是前提是:wait方法必须放进同步控制(synchronized)方法或同步控制块中。
      

  9.   


    对 程序员关注的是Erro不是Warnings