0

我想尝试使用对象本机方法 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 建议,有必要在调用 wait 或 notify 之前对对象进行同步……我们开始吧:

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;

}


}
4

1 回答 1

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;
    }
}
于 2013-02-23T19:42:36.233 回答