[java] Problem with multithreading

Started by
3 comments, last by etothex 18 years, 5 months ago
Ive been working on this all day and I cannot seem to figure it out... any help would be appreciated. These are the rules I must follow... Readers can read the database concurrently. Writers need exclusive access to the database. Two writers cannot have concurrent access to the database. A reader and a writer cannot have concurrent access to the database. When no writer is active, readers must be permitted to access the database concurrently. At the beginning of the reader Class startRead() is called and at the endRead() is called. The same goes for the Writer class. volatile public int accessType = 0; // 0 = No Access // 1 = Reader Accessing // 2 = Writer Accessing volatile public int readers = 0; synchronized public void startRead() throws InterruptedException { if (accessType == 2) { try { wait(); } catch (InterruptedException e) { System.err.println("interrupted out of wait"); } accessType = 1; readers++; } else if (accessType == 1) readers++; else if (accessType == 0) { accessType = 1; readers++; } } synchronized public void endRead() { if (readers == 1) { readers--; accessType = 0; notifyAll(); } else readers--; } synchronized public void startWrite() throws InterruptedException { if (accessType == 1 || accessType == 2) { try { wait(); } catch (InterruptedException e) { System.err.println("interrupted out of wait"); } accessType = 2; } else // if (accessed == true) { accessType = 2; } } synchronized public void endWrite() { accessType = 0; notifyAll(); } For one reason or another threads are not getting blocked from accessing the data... thx in advance
Advertisement
Try:

synchronized public void startWrite() throws InterruptedException{  while (accessType == 1 || accessType == 2) {    try {      wait();    } catch (InterruptedException e) {       System.err.println("interrupted out of wait");     }  }  accessType = 2;}


I don't know why wait() would terminate early (unless something else is calling notify), though

Edit: you might need the same for startRead too
Worked like a charm... thanks so much. Just a quick question if ya dont mind answering it. Why exactly did this work? I thought the wait statement caused the thread to halt.. I dont see why you would need to loop through.
The reason it works is because wait(), it seems, will prematurely return.

This is possibly because you use notifyAll(), which wakes up all threads running wait(), instead of notify(), which only wakes up one thread running wait(). If you had two threads running start*() functions, when endRead or endWrite was called, both start* functions would wake up and get the lock.

wait() and notify() are methods of waiting for and signaling a state change in the object; wait() stops the thread until another thread indicates that something has changed, and now it's time for the waiting thread to reevaluate the situation.

Consider: if you had to do this without wait(), you could do a busy-wait by doing:

while (accessType == 1 || accessType == 2) { }


which would not go forward until accessType==0. However this hogs the CPU, as there's no need to check if it has changed to 0 until someone tells us the state of the object has changed, via a notify() call, so we wait.

So what happens, you check if accessType == 0, and if not, you wait until the state changes - then you have to check again to see if accessType really changed, or if it was just a false alarm because something else changed. You could avoid using while if you replace wait()/notify() with a dedicated binary semaphore, but really that's just overkill most of the time.
One note, I just found out that wait() may spontaniously return without anyone calling notify() or notifyAll(), or any timeout expiring.

That is, the proper behavior regarding wait cannot be guaranteed - the only thing that is sure is that calling notify() will wake up a wait() somewhere(unless there is no wait). Otherwise, a return from wait does not mean that a notify() was called.

This topic is closed to new replies.

Advertisement