0

I am learning concurrency in Java, and came to know about semaphores, which can be used for synchronisation without busy waiting.

Now, I'm wondering if Java synchronised method/statements and locks (e.g. re-entrant lock) are busy waiting mechanisms?

If not, how do other thread(s) get notified, do they implement semaphores under the hood?

synchronised method()
synchronised(object){}
reeantrant.lock()
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Rajat Aggarwal
  • 392
  • 3
  • 16
  • Does this answer your question? [Synchronized keyword internal implementation](https://stackoverflow.com/questions/25949145/synchronized-keyword-internal-implementation) – Savior Oct 07 '21 at 19:36
  • 2
    This isn't specified in the language, but it's well known that Java will optimize its locks according to how they are used. Locks that have little contention will use busy waiting (so called spin-lock) and locks with frequent contention will block to avoid using too much CPU. – markspace Oct 07 '21 at 19:37
  • 1
    There's other stuff going on behind the scenes too, like "biased locks" that are "owned" by and biased towards one particular thread. I know a lot less about how that implementation works, and what other optimizations the JVM might perform. – markspace Oct 07 '21 at 19:40
  • @markspace so, i can use synchronised keyword without worrying about busy waiting? – Rajat Aggarwal Oct 07 '21 at 19:41
  • 2
    Yup, the JVM will figure it out and use the best implementation for you. Virtual Machines are handy like that, you aren't stuck with one static code implementation determined at compile time. – markspace Oct 07 '21 at 19:42

1 Answers1

1

how do other thread(s)get notified,

Virtually all practical JVMs let the operating system do the real work. workstations, servers, and mobile devices all run preemptive, multi-tasking operating systems these days, and it's the operating system that provides the primitive functions upon which threads, mutexes, semaphores, etc. are all built.

The most important thing that the OS can do that programs can't do for themselves is called a context switch. That's where the OS suspends one thread, saves its state in a special "context record," and then restores the context of some other thread, allowing the second thread to start using the same CPU that the first thread previously was using.

Whenever a thread waits to lock a mutex, waits for I/O, for some_object.notify(), or for pretty much anything else, the OS "switches out" its context, places it in a queue of things that are awaiting that event, and we say that the thread is blocked on the event. When the event happens (e.g., when somebody releases a mutex) the OS moves the thread's context into a queue of threads that are RUNNABLE, and eventually, when a CPU becomes available, it "switches in" the context, and the thread gets to run again.

do they implement semaphores under the hood?

Semaphore is a very old idea: It originally was meant to be a low-level primitive operation--one that could be implemented in an arcane way, without any hardware support--upon which other things like mutual exclusion, queues, barriers, etc. could be built.

These days, mutexes are the lowest level--implemented using special hardware instructions--and a semaphore is a higher level object that is built on top of a mutex. One of the main reasons we still have Semaphore is just that so much of the existing literature talks about semaphores, and so much existing code still uses semaphores.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57