GeeCON Prague 2014*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes URLyBird 1.3.1: Locking Problem Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "URLyBird 1.3.1: Locking Problem" Watch "URLyBird 1.3.1: Locking Problem" New topic
Author

URLyBird 1.3.1: Locking Problem

Leo Ho
Ranch Hand

Joined: Mar 31, 2005
Posts: 36
Hi folks, I'm doing locking on the server-side (e.g having a biz layer with methods such as book(), search() etc.) and stuck with the following situation:

- Thread A gets lock for Record 1 -> OK
- Thread B gets lock for Record 2 -> OK
- Thread C gets lock for Record 1 -> fail, wait()
- Thread D gets lock for Record 2 -> fail, wait()
- Thread A finishes record 1 and notifyAll() -> the scheduler chooses Thread D to run, but Thread D still cannot lock record 2, thus wait() (so we still have C, D in the waiting queue)
- Thread B finishes record 2 and notifyAll() -> the scheduler chooses Thread C to run, similarly Thread C still cannot lock record 1, thus wait()

-> Thread C, D wait forever.

How you guys handle this situation???

In addition, by reading through many posts, can s/o comfirm me the following: if I do server-side locking (e.g. book() which calls lock(), read(), delete(), unlock() respectively) then I don't have to be worried about WeakHashMap or Unreferenced since there won't be any case that unlock() cannot be called, is that right?

Many thanks,

Leo
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
Thread A finishes record 1 and notifyAll() -> the scheduler chooses Thread D to run,


Huh? Thread A notifies all threads waiting on record 1, not record 2. So Thread D will not be woken, but thread C will.


Ask a Meaningful Question and HowToAskQuestionsOnJavaRanch
Getting someone to think and try something out is much more useful than just telling them the answer.
Leo Ho
Ranch Hand

Joined: Mar 31, 2005
Posts: 36
Originally posted by Barry Gaunt:


Huh? Thread A notifies all threads waiting on record 1, not record 2. So Thread D will not be woken, but thread C will.


How can you do that??? My current implementation is using one lock for all the record locks, thus when you call lock.notifyAll(), you don't know which threads will get notified -> my situation. Can you add details to your solution?

Leo
B Chen
Ranch Hand

Joined: Dec 27, 2005
Posts: 89
I thought that when you use notifyAll(), all threads waiting on the object will wake up? So both thread C and D should have woken. But only one of them will be able to continue working. The other one will go back to waiting.
If you called notify(), then the scheduler will choose one waiting thread to wake up. And it may choose the "wrong" thread because the record it is waiting for has not been released.
[ April 12, 2006: Message edited by: B Chen ]

SCJD<br />SCJP 1.4
Leo Ho
Ranch Hand

Joined: Mar 31, 2005
Posts: 36
Originally posted by B Chen:
I thought that when you use notifyAll(), all threads waiting on the object will wake up? So both thread C and D should have woken. But only one of them will be able to continue working. The other one will go back to waiting.


Nope, notifyAll() do wake up all threads, but they will then compete to get the lock and only one of them can get execute - otherwise you will have multiple threads in your critical section.

Leo
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
My current implementation is using one lock for all the record locks


You did not write that in your original post. If it's so how do you have:

Thread A gets lock for Record 1 -> OK
Thread B gets lock for Record 2 -> OK


holding the lock at the same time?
B Chen
Ranch Hand

Joined: Dec 27, 2005
Posts: 89
Originally posted by Leo Ho:


Nope, notifyAll() do wake up all threads, but they will then compete to get the lock and only one of them can get execute - otherwise you will have multiple threads in your critical section.

Leo


All the waiting threads wakened by notifyAll will, in turn, execute the code in the critical section. For example:

Thread A acquires mutex
Thread B, finding the mutex already lock, waits
Thread C, finding the mutex already lock, waits
Thread A finishes its work, does notifyAll(), and releases mutex
Thread B and C both wake up and compete for mutex
Thread C acquires mutex, does its work, and releases
Thread B acquires mutex, does its work, and releases

It could be that thread B acquires the lock first. But the point is, the second thread will acquire the monitor after the first thread is done.
[ April 12, 2006: Message edited by: B Chen ]
Leo Ho
Ranch Hand

Joined: Mar 31, 2005
Posts: 36
Oh man, I just got screwed up about threading. I thought that even if all threads get notifyAll(), only one of them will acquire the lock and run while the others continue living in the wait state - which is of course very wrong.

Thanks Chen, you're exactly right.

Leo
 
GeeCON Prague 2014
 
subject: URLyBird 1.3.1: Locking Problem