DEV Community

Code Craft Club
Code Craft Club

Posted on • Originally published at Medium

Semaphores, is that so easy!! The Clothing Store Analogy as a Guide for Beginners

Introduction to Semaphores

Semaphores are a synchronization mechanism used in computer science to control access to a shared resource, such as a variable or a section of code usually known as the Critical Section, in a multithreaded or multi-process environment. They help ensure that multiple threads or processes can access the resource in a coordinated and safe manner.

Let's use the analogy of a clothing store to understand the concept of semaphores and why they are needed for parallel processing.

The Clothing Store Analogy

Imagine a clothing store that can only hold a maximum of 5 items inside. There are Tailors (producers) who are continuously creating new items, and customers (consumers) who are eagerly buying them. Here are the key conditions of this analogy:

  1. Store Capacity: The store can store a maximum of 5 items at a time.
  2. Continuous Production: Producers replenish items as soon as the count decreases to ensure the store doesn't run out of stock.
  3. Continuous Consumption: Customers only buy products when items are available in the store.
  4. No Out-of-Stock: At any point, a customer should not encounter an out-of-stock situation.

Clothing Store

Now in this scenario, let’s understand the possibilities without the use of semaphores. Since there are multiple producers (tailors) and consumers (customers), everyone would try to access the store concurrently. This can lead to several issues:

  1. Race Conditions: Without synchronization, there's no guarantee that one thread won't interrupt another while accessing shared resources like the item count in the store. This can lead to race conditions where the final outcome depends on the order of execution.
  2. Inconsistent State: Due to race conditions, the item count in the store may become inconsistent. Producers might add items simultaneously, causing the count to go beyond the store's capacity or even drop below zero, leading to illogical scenarios.
  3. Out-of-Stock Problems: Consumers may try to buy items even when none are available, resulting in out-of-stock situations. Conversely, producers may overstock the store, wasting resources.
  4. Deadlocks: In complex scenarios, without proper synchronization, threads might end up in a deadlock, where they're stuck, unable to proceed because they're all waiting for a resource that won't be released.

Let’s implement the analogy in code and check the issues as discussed above.

Creating the Java Classes

To implement this analogy, we'll create three Java classes: Store, Producer, and Consumer.

The Store Class (Critical Section)

The Store class represents our shared resource, the clothing store. It contains the current item count.

Store class

The Producer Class

The Producer class represents tailors who continuously produce items and add them to the store. We are using the Runnable interface to let them run using separate threads.

Producer Class

The Consumer Class

The Consumer class represents customers who continuously buy items from the store. We are using the Runnable interface to let them run using separate threads.

Consumer class

The Main Method

In the Main method, we'll create 10 producers and 10 consumers as separate threads and start them to simulate the store scenario.

Main class

The above program when executed would give rise to Index out of bounds issues.

With Semaphores → Order is Restored

Now, let's introduce semaphores to our scenario, and watch as they bring order to the chaos. To implement the semaphores, we need to add the changes in the Main class, Producer class and Consumer class.

Adding Semaphores in the Main class

Main class with Semaphores

Adding Semaphores in the Producer class

Producer class with semaphores

Adding Semaphores in the Consumer class

Consumer class with semaphores

With the above modifications by adding semaphores:

Mutex Semaphore: This ensures exclusive access to the critical section (the store) by allowing only one thread in at a time. This prevents race conditions and ensures that changes to the item count are made one at a time.

Controlled Access: Producers and consumers must acquire a permit before entering the store (critical section). If the store is full (5 items), producers will wait until a consumer buys something, freeing up space. Similarly, consumers will wait if the store is empty until a producer adds an item.

Consistent State: Semaphores ensure that the item count remains consistent and within the store's capacity. Producers and consumers work together harmoniously to maintain the correct item count.

No Deadlocks: Semaphores provide a straightforward mechanism for controlling access, reducing the likelihood of deadlocks. Threads can always access the critical section eventually, avoiding deadlock scenarios.

In short, Semaphores are just like the traffic cops!!

Traffic cops

Conclusion

By using semaphores, we transform our chaotic scenario into a well-behaved system, ensuring a smooth shopping experience for both producers and consumers.


Closing Thoughts:

Thank you for reading our blog. We appreciate your time and interest in our content. If you have any questions, feedback, or topics you’d like us to cover in our future articles, please feel free to leave a comment below. Your input is valuable, and it helps us create content that matters to you.

Stay connected with us for more insightful articles on various topics related to technology, programming, and much more.

Happy coding!

Top comments (0)