Concurrency – Producer & Consumer in java (Wait notify example)

By | August 30, 2017
  • Given multi-threading application in java.
  • Create Producer & Consumer threads.
    • Producer thread will produces the data.
    • Consumer thread will consumes the data.
    • Synchronize Producer & Consumer thread using wait & notify methods.

1. DataStore class:

  • DataStore class contains LinkedList to store integer values.
  • DataStore class contains two synchronized methods i.e. get & put
    • put method: insert random value to LinkedList of integers.
    • get method: retrieve value from LinkedList of integers.
  • put method:
    • Thread will wait if LinkedList has reached threadhold size.
    • If size of LinkedList is less than threadhold size then insert random integer value to LinkedList.
  • get method:
    • Thread will wait if LinkedList is empty.
    • If LinkedList has any element then retrieve value from LinkedList.
package org.learn.sync.wn;

import java.util.LinkedList;
import java.util.Random;

public class DataStore {
    public int storeSize;
    public LinkedList<Integer> store;

    Random random = new Random(1000);

    public DataStore(int size) {
        storeSize = size;
        store = new LinkedList<>();
    }

    public synchronized void put() {

        if(store.size() == storeSize) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        int putValue = random.nextInt(1000);
        store.offer(putValue);
        System.out.printf("Putting : Value = %d\n", putValue);
        notifyAll();
    }

    public synchronized void get() {

        if(store.size() == 0 ){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        int value = store.poll();
        System.out.printf("Getting Value : %d \n",value);
        notifyAll();
    }
}

2. Producer class:

  • Producer class is responsible for putting the data in DataStore class.
  • Producer class implements Runnable interface and put value in DataStore.
package org.learn.sync.wn;


public class Producer implements Runnable {

    private DataStore dataStore;
    private int numberOfItems;
    public Producer(DataStore dataStore, int numberOfItems) {
        this.dataStore = dataStore;
        this.numberOfItems = numberOfItems;
    }
    @Override
    public void run() {

        for(int count = 0; count < numberOfItems; count++) {
            dataStore.put();
        }
    }
}

3. Consumer class:

  • Consumer class is responsible for getting the data in DataStore class.
  • Producer class implements Runnable interface and retrieve value from DataStore,
package org.learn.sync.wn;

public class Consumer implements Runnable {

    private DataStore dataStore;
    private int numberOfItems;

    public Consumer(DataStore dataStore, int numberOfItems) {
        this.dataStore = dataStore;
        this.numberOfItems = numberOfItems;
    }

    @Override
    public void run() {

        for(int count = 0; count < numberOfItems; count++) {
            dataStore.get();
        }
    }
}

4. WaitNotifyExample class:

  • WaitNotifyExample class contains main method to simulate Producer & Consumer scenario.
  • We will create producer & consumer threads to simulate wait & notify scenario.
package org.learn.sync.wn;

public class WaitNotifyExample {

    public static void main(String[] args) throws InterruptedException {

        DataStore dataStore = new DataStore(10);

        Thread producer = new Thread(new Producer(dataStore, 20),"ProducerThread");
        Thread consumer = new Thread(new Consumer(dataStore, 20),"ConsumerThread");

        producer.start();
        consumer.start();

        producer.join();
        consumer.join();
    }
}

5. Output: Producer & Consumer scenario using wait & notify in java


ProducerThread, Putting : Value = 487
ProducerThread, Putting : Value = 935
ProducerThread, Putting : Value = 676
ProducerThread, Putting : Value = 124
ProducerThread, Putting : Value = 792
ProducerThread, Putting : Value = 349
ProducerThread, Putting : Value = 641
ProducerThread, Putting : Value = 845
ProducerThread, Putting : Value = 264
ProducerThread, Putting : Value = 450
ConsumerThread, Getting : Value = 487
ConsumerThread, Getting : Value = 935
ConsumerThread, Getting : Value = 676
ConsumerThread, Getting : Value = 124
ConsumerThread, Getting : Value = 792
ConsumerThread, Getting : Value = 349
ConsumerThread, Getting : Value = 641
ConsumerThread, Getting : Value = 845
ConsumerThread, Getting : Value = 264
ConsumerThread, Getting : Value = 450
ProducerThread, Putting : Value = 379
ProducerThread, Putting : Value = 159
ProducerThread, Putting : Value = 372
ProducerThread, Putting : Value = 383
ProducerThread, Putting : Value = 836
ProducerThread, Putting : Value = 475
ProducerThread, Putting : Value = 646
ProducerThread, Putting : Value = 2
ProducerThread, Putting : Value = 323
ProducerThread, Putting : Value = 241
ConsumerThread, Getting : Value = 379
ConsumerThread, Getting : Value = 159
ConsumerThread, Getting : Value = 372
ConsumerThread, Getting : Value = 383
ConsumerThread, Getting : Value = 836
ConsumerThread, Getting : Value = 475
ConsumerThread, Getting : Value = 646
ConsumerThread, Getting : Value = 2
ConsumerThread, Getting : Value = 323
ConsumerThread, Getting : Value = 241