5

If you look at documentation describing the usage of condition variables (cv), you'll see that e.g. in PThreads and C++ you don't need to hold the mutex of a cv to call notify on this cv. Whereas e.g. in Java and Python, you must lock the mutex to do the same thing.

Is there some deep reason why things are implemented this way (I'm about the latter case), given that an implementation of a language like Java eventually uses some native threading tools?

alk
  • 69,737
  • 10
  • 105
  • 255
vehsakul
  • 1,118
  • 1
  • 10
  • 17
  • Probably it's not implemented on top of just pthreads .. but that is just an assumption. I feel this question might get better (or even *any*) answers on http://cs.stackexchange.com/ ... –  Sep 12 '15 at 10:59
  • Obviously the JVM could implement it like that, but it makes a common mistake that I've seen many, many people do in c++ much less likely at a reasonably low cost (you need to hold a lock a bit longer but that's it) – Voo Sep 12 '15 at 14:39
  • @Voo The mistake being that the mutex is not held while modifying the data the condition depends on? – vehsakul Sep 12 '15 at 17:34
  • @vehsakul Checking the *condition* (which usually depends on the data being modified) without holding the lock. Yes there are situations where this is perfectly valid, but it creates a big opportunity for bugs. Managed languages are in the end all about trading performance *options* for safety. Personally I find the tradeoff reasonable here, I don't think there are many real life examples where it'd make a big difference. – Voo Sep 12 '15 at 17:45
  • @Voo Ok, your point about safety vs. performance is clear. – vehsakul Sep 12 '15 at 18:35
  • Also if using the PThreads-API from C/C++ it is good practice to lock the condition's mutex before signalling the condition as if not (citing POSIX ) "*The thread(s) that are unblocked shall contend for the mutex according*" and "*if predictable scheduling behavior is required, then that mutex shall be locked by the thread calling pthread_cond_broadcast() or pthread_cond_signal().*". http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_broadcast.html – alk Sep 13 '15 at 16:21

1 Answers1

1

The Java notify and notifyAll basic synchronization tools both require you to synchronize on the object before calling them. This is for a simple safety point since it also requires you to synchronize on them before waiting.

For example if you have two threads. One thread reads data from a buffer and one thread writes data into the buffer.

The reading data thread needs to wait until the writing data thread has finished writing a block of data into the buffer and then it can read the block.

If wait(), notify(), and notifyAll() methods can be called without synchronization then you can get a race condition where:

  • The reading thread calls wait() and the thread is added to waiting queue.

  • At the same time, the writing thread calls notify() to signal it has added data.

  • The reading thread misses the change and waits forever since the notify() was processed before the wait() was.

By forcing the wait and notify to happen within a synchronized block this race condition is removed.

Tim B
  • 40,716
  • 16
  • 83
  • 128