0

Condition 変数の代わりにオブジェクト ネイティブ メソッドの wait() と notify() を使用しようとしましたが、これにより 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;

}


}
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 に答える