In this post, we will have a look on how to manually implement the wait/notify using synchronized block in order to handle the producer consumer scenario in java.
What is Producer Consumer in Java?
Producer - A producer in Java is a thread that runs independently that produces something that is going to be consumed by a single Consumer or a group of Consumers.
Consumer - A Consumer in Java is a thread that runs independently and consumes something produced by a single producer or a group of Producers.
pro Producer/Consumer implmentation is required in java when instead of running a complete process in a single thread, the division takes place to run a process in order to speed up the process.
The basics of this post:
1) Producer/Consumer will be having a list and maximum size.
2) Producer keep on adding the integer in the list.
3) Consumer reads the value from the list at last position and removes it.
4) As soon as list reached the maximum size defined by the client, it wait for the consumer to read atleast one value and remove it.
5) As soon as list goes empty, Consumer waits for the producer to add atleast one value in the list.
6) The process can run indefinetlt or as per defined by the client.
Producer.java
package com.thred.waitnotify; import java.util.List; public class Producer implements Runnable { private List<Integer> list; private Integer limit; public Producer(List<Integer> list, Integer limit) { super(); this.list = list; this.limit = limit; } @Override public void run() { Integer count = 0; while (true) { while (list.size() == limit) { synchronized (list) { System.out.println("List if full. " + Thread.currentThread().getName() + " is waiting , size: " + list.size()); try { list.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } synchronized (list) { list.add(count++); System.out.println("Produced : " + count); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } list.notifyAll(); } } } }
Consumer.java
package com.thred.waitnotify; import java.util.List; public class Consumer implements Runnable { private List<Integer> list; private Integer limit; public Consumer(List<Integer> list, Integer limit) { super(); this.list = list; this.limit = limit; } @Override public void run() { while (true) { while (list.isEmpty()) { synchronized (list) { System.out.println("Queue is empty " + Thread.currentThread().getName() + " is waiting , size: " + list.size()); try { list.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // Otherwise consume element and notify waiting producer synchronized (list) { System.out.println("Consumed : " + list.remove(list.size() - 1)); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } list.notifyAll(); } } } }
ClientProdCons.java
package com.thred.waitnotify; import java.util.ArrayList; import java.util.List; public class ClientProdCons { public static void main(String args[]) { List<Integer> sharedQueue = new ArrayList<Integer>(); int size = 10; Thread prodThread = new Thread(new Producer(sharedQueue, size), "Producer"); Thread consThread = new Thread(new Consumer(sharedQueue, size), "Consumer"); prodThread.start(); consThread.start(); } }
Output
Produced : 1
Produced : 2
Consumed : 1
Consumed : 0
Queue is empty Consumer is waiting , size: 0
Produced : 3
Produced : 4
Produced : 5
Produced : 6
Consumed : 5
Consumed : 4
Consumed : 3
Consumed : 2
Queue is empty Consumer is waiting , size: 0
Produced : 7
Produced : 8
Produced : 9
Consumed : 8
Consumed : 7
Consumed : 6
Queue is empty Consumer is waiting , size: 0
Produced : 10
Produced : 11
To download source, click here
No comments:
Post a Comment