你能解释为什么这些代码会引发异常吗?

时间:2013-02-23 19:15:21

标签: java

我想尝试使用Object本机方法wait()和notify()而不是Condition变量,但这会引发IllegalMonitorStateException ...请问您能解释一下如何使用它吗?

package monitor;


public class MyMonitor {

private long threadID=0;

Object okToWrite = new Object();
Object okToRead = new Object();

synchronized public void insertID() throws InterruptedException {
    if (this.threadID != 0) {
            okToWrite.wait();
    }

    this.threadID = Thread.currentThread().getId();
    okToRead.notify();

}

synchronized public long getID() throws InterruptedException {
    long res;

    if (this.threadID == 0) {
        okToRead.wait();
    }

    System.out.println(this.threadID);
    res = this.threadID;
    this.threadID = 0;
    okToWrite.notify();

    return res;

}


}

我是否需要进一步锁定对象?

更新: Ad Neil建议,有必要在呼叫等待或通知之前同步对象...这里我们去:

package monitor;


public class MyMonitor {

private long threadID=0;

Object okToWrite = new Object();
Object okToRead = new Object();

public void insertID() throws InterruptedException {
    if (this.threadID != 0) {
        synchronized(okToWrite) {
            okToWrite.wait();
        }
    }

    this.threadID = Thread.currentThread().getId();
    synchronized(okToRead) {
        okToRead.notify();
    }

}

public long getID() throws InterruptedException {
    long res;

    if (this.threadID == 0) {
        synchronized(okToRead) {
            okToRead.wait();
        }
    }

    System.out.println(this.threadID);
    res = this.threadID;
    this.threadID = 0;
    synchronized(okToWrite) {
        okToWrite.notify();
    }

    return res;

}


}

1 个答案:

答案 0 :(得分:1)

您可以通过同步要等待或通知的对象来使代码工作,但我只是同步监视器对象上的所有内容:

package monitor;

public class MyMonitor {
    private long threadID = 0;

    synchronized public void insertID() throws InterruptedException {
        while (this.threadID != 0) {
            wait();
        }

        this.threadID = Thread.currentThread().getId();
        notify();
    }

    synchronized public long getID() throws InterruptedException {
        while (this.threadID == 0) {
            wait();
        }

        long res = this.threadID;
        this.threadID = 0;
        notify();

        return res;
    }
}