File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Threads and Synchronization and the fly likes Why does Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Why does "notify" need to be synchronized ?" Watch "Why does "notify" need to be synchronized ?" New topic
Author

Why does "notify" need to be synchronized ?

Sol Mayer-Orn
Ranch Hand

Joined: Nov 13, 2002
Posts: 311
Why do they required that "Object.notify" be called only while holding the lock:


I'm been asking around for *ages* ...

It's true that logically, it's *likely* that whoever called "notify", did so right after performing changes to some shared data. In which case they're likely to be holding the lock anyway. But that's not a good enough reason... the fact it's logically likely, doesn't explain why they decided to *mandate* it on a technical level...

Thanks
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Notify tells some object that is waiting on a monitor that the monitor is about to become available. Only the owner of the monitor can do this because only the owner knows when it's about to give the monitor up. From the JavaDoc

This method should only be called by a thread that is the owner of this object's monitor. A thread becomes the owner of the object's monitor in one of three ways:

* By executing a synchronized instance method of that object.
* By executing the body of a synchronized statement that synchronizes on the object.
* For objects of type Class, by executing a synchronized static method of that class.


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18120
    
  39

I'm been asking around for *ages* ...

It's true that logically, it's *likely* that whoever called "notify", did so right after performing changes to some shared data. In which case they're likely to be holding the lock anyway. But that's not a good enough reason... the fact it's logically likely, doesn't explain why they decided to *mandate* it on a technical level...


This one is weird... I'll try to answer it this way. Let's look at the wait() method...

Just like notify(), it is likely that whoever called wait() will be checking on some shared data. Unlike notify(), it has an extra task to do, it needs to release the locks on that shared data, or else, the data can't be changed to the state that it is waiting for.

Unfortunately, there is *no* way to do this, in java code, without encountering a race condition. The locks must be freed by the wait() method, and must be re-acquired by the wait() method, by some native code that will prevent the race condition. (You also have the problem of releasing *all* of the locks)

Anyway, I believe this is the reason why it was "mandated" for the wait() method call. And the notify() method call probably got "mandated" to be consistent.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18120
    
  39

Also, forgot to mention... If you look at any other threading system, such as Solaris threads, POSIX threads, etc., they all require that a mutex be held while using any condition variable. In this regard, Java is no different.

Henry
Warren Dew
blacksmith
Ranch Hand

Joined: Mar 04, 2004
Posts: 1332
    
    1
There may be an implementation issue as well.

Since Java uses native threads, the notification itself, at the native code level, needs to be thread safe, so that only one thread runs the native notification code at a time - otherwise you could have two waiting threads simultaneously being notified when you only wanted one. The simplest way to ensure the notification is thread safe is to have the notification lock on the same object the wait() methods locked on. Since this has to happen at the native code level anyway, it's clearer to require the source code to reflect it.
D Rog
Ranch Hand

Joined: Feb 07, 2004
Posts: 472

Maybe it can be solved declaring notify as
public synchronized void notify() {
callNativeNotify(this);
}


Retire your iPod and start with HD Android music player Kamerton | Minimal J2EE container is here | Light weight full J2EE stack | and build tool | Co-author of "Windows programming in Turbo Pascal"
Sol Mayer-Orn
Ranch Hand

Joined: Nov 13, 2002
Posts: 311
Thanks so much for the great replies.

So if I understand correctly: notify will end up requiring some synchronization on the native/lower level, when accessing the queue of waiting threass. So might as well let the programmer decide when exactly to lock (and avoid redunent lower-level locking).
Sounds quite convincing to me. Too bad the spec doesn't say anything about it (it says you should lock, but not why).


Henry Wong, thanks very much for the POSIX reference. Does POSIX document the motivation for it (is it indeed the requirement for low-level lock on the wating queue) ?

Also, forgot to mention... If you look at any other threading system, such as Solaris threads, POSIX threads, etc., they all require that a mutex be held while using any condition variable. In this regard, Java is no different.


Thanks again
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Why does "notify" need to be synchronized ?
 
Similar Threads
Thread Monitor
locks and monitor
Beginner: Threads vs. Runnables
Threads k&B page 720
wait() without notify()/notifyAll()