SagittariusA
SagittariusA

Reputation: 5427

Could you please explain why this codes raises exception?

I wanted to try to use Object native methods wait() and notify() instead of Condition variable but this raises IllegalMonitorStateException...could you please explain how to use it?

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;

}


}

Do I need further locks for Object?

UPDATE: Ad Neil suggested, it is necessary to synchronize on the object before call wait or notify...here we go:

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;

}


}

Upvotes: 0

Views: 67

Answers (1)

Neil
Neil

Reputation: 55392

You could probably get your code to work by synchronising on the objects that you want to wait or notify on, but I would just synchronise everything on the monitor object:

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;
    }
}

Upvotes: 1

Related Questions