Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are Java wait(), notify() 's implementation significantly different from locks?

Out of curiosity, when Java implements wait() and notify() methods, are they really just using locks? i.e., wait() acquires a mutex, notify() release a mutex, notifyAll() releases all mutexes (in the same object, of course)?

Other than being less cumbersome than using locks, are there other advantages of using wait() and notify()?

[EDIT] I realized what I confused myself about after Brian's comments:

wait doesn't lock, it releases the lock and passes it to someone else who's waiting on a synchronized statement for the mutex, then waits to be notified by someone else who has the lock and calls notify, which passes the lock back to the original thread that called wait. I think that's where you're getting confused. – Brian 17 mins ago

like image 815
CuriousMind Avatar asked Jun 23 '13 03:06

CuriousMind


2 Answers

The other questions have focused on what the language says that wait and notify are - but that doesn't seem to be what your question is about... you talk about mutexes, which is an implementation detail and therefore JVM specific.

So we need to pick a JVM - let's pick openjdk (source available here). The bit of code that (ultimately) handles all this stuff is found at hotspot/src/share/vm/runtime/objectMonitor.cpp.

This maintains two datastructures - a wait set and an entry set. Waiting threads are added to the wait set and parked whereas threads attempting to take the monitor are added to the entry set and then parked. On notify a thread is taken from the wait set and added to the entry set. When a thread releases the lock it unparks a thread from the entry set if there is one. Note that these sets are actually implemented as queues (linked lists) so are treated on a FIFO basis.

Therefore, in this particular case the implementation treats waiting on an object's monitor and attempting to take an object's monitor in a similar way.

But this is just one implementation of one JVM (although it's likely that others do something similar) - so we cannot rely on it. So I suppose the question is why do you want to know? If it's just curiosity then look through the openjdk code, it's fascinating. If you plan on using this information in your code... don't.

UPDATE

I realise that saying "park" doesn't tell us much. The code that parks a thread is platform specific (and is implemented in an object called PlatformEvent, which ParkEvent extends). In the version of openjdk that I'm looking at the park code for linux can be found at hotspot/src/os/linux/vm/os_linux.cpp and this calls pthread_mutex_lock(_mutex)... so in answer to your question yes calling wait may take a mutex on my machine. Note that there's lots of stuff that happens above this which might prevent us getting to this point.

like image 152
selig Avatar answered Sep 30 '22 02:09

selig


wait() and notify() don't do any monitor acquisition. as the javadoc for these methods state, the caller must have acquired the monitor before calling. in fact, wait() actually releases the monitor the caller acquired (although, i guess technically wait does do monitor (re)acquisition before finally returning).

like image 38
jtahlborn Avatar answered Sep 30 '22 02:09

jtahlborn