Understanding Multi-threading in Java: Essential Basics - Part 2
In a previous article, we began exploring the essential concepts related to multi-threading. Let’s continue delving into these more abstract ideas before moving on to practical Java examples.
Mutex vs. Semaphore
Let’s dive into two concurrency constructs and the differences among them. Both of these concepts are lower-level (OS-level ) constructs.
Mutex: refers to mutual exclusion, and it’s used for guarding shared data. A mutex owned by a thread will have exclusive access to act upon the shared data source. Only once the mutex is released by the thread which acquired it in the first place, can give the chance to other threads to compete and acquire the lock.
Semaphore: In contrast to mutex, semaphore guards limited resources. Semaphores only have a limited number of permits to give out - let’s say 5 as an example. If 10 threads are entering the semaphore to request to be executed, only 5 can go ahead but the other 5 will have to wait until some of the permits are released. Consequently, there is no idea of ownership here unlike with mutexes. Additionally, semaphores can also be used for signalling whereas mutex is only concerned with guarding access to critical sections.
Critical sections and race conditions are another two important concepts related to concurrency mentioned which have not been covered here yet. Critical sections refer to the data which is shared by the process to all of its threads. When several threads race through the data to read/write to it that can result in inconsistent/ corrupted data. This is referred to by the term race conditions. We will see this through practical examples.
It is possible to have a semaphore with only one permit which is called binary semaphore - yet, it’s not equivalent to a mutex. A mutex has to be acquired and released by the same thread whereas in semaphore different threads can acquire a lock and release it.
Mutex | Semaphore | |
Protects | Shared data | Limited resources (permits) |
Ownership | Exists - mutex is owned by a thread | Have no notion of ownership |
Signalling | N/A | Can be used for signalling |
Mutex vs. monitor
As mentioned before, while a mutex is a lower-level - OS-level construct, the monitor is a programming language-level construct. Monitors are provided in Java as well.
The monitor can be defined as a mutex with one or more condition variables. In Java, every object is a monitor, with an associated lock and condition variable. Each object exposes wait() and notify()/notifyAll() methods.
From now on, let’s start exploring the previously mentioned concepts through practical examples written in Java:
Crafting Thread-Safe Functions in Java - Part 1
Subscribe to my newsletter
Read articles from Her Code Review directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by