profile

Islam Zaoui

Full Stack Web Developer

Back

Producer Consumer Problem in java

How to solve the Producer-Consumer Problem in java using semaphores and manager 5 months ago

What is the Producer-Consumer Problem?

The Producer-Consumer Problem, also known as the Bounded Buffer Problem, entails multiple threads operating as either producers or consumers, sharing a common buffer (or storage).

  1. The Producer generates an item and adds it to the shared buffer.
  2. The Consumer retrieves an item from the same buffer for consumption.

Accessing a buffer without synchronization methods can lead to data corruption, race conditions, and undefined behavior. Race conditions occur when multiple threads access shared resources concurrently without proper synchronization, leading to unpredictable outcomes. In the context of buffer access, this means that one thread might be reading from or writing to the buffer while another thread is also attempting to read from or write to it simultaneously. This can result in interleaved or partial data being read or written, leading to corrupted or inconsistent data.

In extreme cases, such as when multiple threads attempt to modify the same data simultaneously, it can lead to a situation where the data becomes completely corrupted or nonsensical. This is commonly referred to as "data corruption" or "data integrity issues."

To avoid such problems, synchronization mechanisms such as locks, semaphores, or mutexes are used to coordinate access to shared resources like buffers among multiple threads. These mechanisms ensure that only one thread can access the buffer at a time, preventing race conditions and maintaining data integrity.

In our case, we will use semaphores to fix this issue.

My Implementation of Producer-Consumer in Java

First of all, I added a few unique things to this problem which is:

  1. Producer generation rate of products controlled by a function that decreases the sleep time of the thread by the increase of the consumer threads count.

  2. Manager thread to control Producer generation of a product by pausing Producer thread when the buffer reaches max size and continuing after the buffer is about to be empty.

Now let's start with coding in Java

Semaphore class

You can skip this and use the Java default Semaphore class

Loading...

this class will help us to synchronize the thread's access to the critical section which is the buffer.

Stock class

This is the buffer class I named it stock and we will store it the products (just random numbers) generated by the Producer thread in it.

Loading...

Factory Thread

The factory thread will generate products and it's will be stored in stock.

Loading...

and don't forget the util class that has the function that controls the producer generation rate.

Loading...

Client Thread

The Client threads will consume the product from the stock.

Loading...

Now for the most important thread in my implementation

Manager Thread

This thread init the semaphores for the synchronization and also stock and factory and will monitor the producer thread status and stock, when the buffer is full it will pause the production and when the buffer is about to be empty it will resume the production.

Loading...

Finally thing is set

Main Class

After you implement every class and thread when executing the main function.

Loading...

The output should be like this:

Loading...

When the stock fills up:

Loading...

When the stock is about to run out:

Loading...

Full Java implementation is here on my repo Producer-Consumer-Java

loading-0loading-1loading-2