3

我的代码给了我一个问题。

IllegalMonitorStateException我的代码在setStrHoge 类中抛出。

Hoge.class换成thisin setStr。我的代码正确完成!

但是为什么正常结束呢?

    public class Sample {
        static Hoge gh = new Hoge();
        static Hoge gh2 = new Hoge();

        public static void main(String[] args) {

            new Thread() {
                private Hoge h2 = gh;
                public void run() {

                    System.out.println("start initialize");
                    h2.setStr("BazzBazz");
                    System.out.println("end   initialize");

                    System.out.println("start thread 1");
                    System.out.println(h2.getStr("thread-1"));
                    System.out.println("end   thread 1");
                }
            }.start();

            new Thread() {
                private Hoge h2 = gh2;

                public void run() {
                    System.out.println("start thread 2");
                    System.out.println(h2.getStr("thread-2"));
                    System.out.println("end   thread 2");
                }
            }.start();
        }
    }

    class Hoge {
        private String fuga = "fugafuga";

        public void setStr(String str) {
            synchronized(Hoge.class) { //<-HERE ! change "Hoge.class" into "this".
                fuga = str;
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        String getStr(String suffix) {
            synchronized(Hoge.class) {
                return suffix+ fuga;
            }
        }
    }
4

2 回答 2

2

因为thisinghgh2不同,this是 Hoge 的一个实例。

所以在使用的时候Hoge.class,没有一个同步锁,而不是使用this哪一个会使用两个不同的锁。

于 2013-03-23T08:37:54.750 回答
2

你的setStr方法应该是这样的:

public void setStr(String str) {
            synchronized(Hoge.class) { //<-HERE ! change "Hoge.class" into "this".
                fuga = str;
                try {
                    Hoge.class.wait();//call wait on Hoge.class 
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

您应该使用Hoge.clas.wait()而不是wait(). 为什么?
因为,正如关于 wait() 的 oracle 文档中所指定的:

此方法只能由作为该对象监视器所有者的线程调用。

即一个thread can't invoke a wait on an object until it owns that object's lock。否则会抛出IllegalMonitorStateException. 在这里,您正在获取Class名为 as 的 Hoge 对象(即 Hoge.class)的锁定class level lock,但正在调用( )wait的当前对象。所以它导致. 这就是为什么当您获取当前对象 ( ) 上的锁定时您的代码工作正常的原因,因为在这种情况下,是在当前对象 ( ) 本身上调用的。HogethisIllegalMonitorStateExceptionthiswait()this

于 2013-03-23T08:41:52.090 回答