diff --git a/pom.xml b/pom.xml
index 4cb30df3f..0222d7e37 100644
--- a/pom.xml
+++ b/pom.xml
@@ -56,6 +56,7 @@
execute-around
property
intercepting-filter
+ producer-consumer
poison-pill
lazy-loading
service-layer
diff --git a/producer-consumer/etc/producer-consumer.png b/producer-consumer/etc/producer-consumer.png
new file mode 100644
index 000000000..e8bc573b3
Binary files /dev/null and b/producer-consumer/etc/producer-consumer.png differ
diff --git a/producer-consumer/etc/producer-consumer.ucls b/producer-consumer/etc/producer-consumer.ucls
new file mode 100644
index 000000000..aa1ee80c0
--- /dev/null
+++ b/producer-consumer/etc/producer-consumer.ucls
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/producer-consumer/index.md b/producer-consumer/index.md
new file mode 100644
index 000000000..58dc45e0d
--- /dev/null
+++ b/producer-consumer/index.md
@@ -0,0 +1,22 @@
+---
+layout: pattern
+title: Producer Consumer
+folder: producer-consumer
+permalink: /patterns/producer-consumer/
+categories: Other
+tags: Java
+---
+
+**Intent:** Producer Consumer Design pattern is a classic concurrency or threading pattern which reduces
+ coupling between Producer and Consumer by separating Identification of work with Execution of
+ Work..
+
+
+
+
+
+**Applicability:** Use the Producer Consumer idiom when
+
+* decouple system by separate work in two process produce and consume.
+* addresses the issue of different timing require to produce work or consuming work
+
diff --git a/producer-consumer/pom.xml b/producer-consumer/pom.xml
new file mode 100644
index 000000000..475c7fb6c
--- /dev/null
+++ b/producer-consumer/pom.xml
@@ -0,0 +1,18 @@
+
+
+ 4.0.0
+
+ com.iluwatar
+ java-design-patterns
+ 1.7.0
+
+ producer-consumer
+
+
+ junit
+ junit
+ test
+
+
+
diff --git a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/App.java b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/App.java
new file mode 100644
index 000000000..50d94d92f
--- /dev/null
+++ b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/App.java
@@ -0,0 +1,57 @@
+package com.iluwatar.producer.consumer;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Producer Consumer Design pattern is a classic concurrency or threading pattern which reduces
+ * coupling between Producer and Consumer by separating Identification of work with Execution of
+ * Work.
+ *
+ * In producer consumer design pattern a shared queue is used to control the flow and this
+ * separation allows you to code producer and consumer separately. It also addresses the issue of
+ * different timing require to produce item or consuming item. by using producer consumer pattern
+ * both Producer and Consumer Thread can work with different speed.
+ *
+ */
+public class App {
+
+ /**
+ * Program entry point
+ *
+ * @param args command line args
+ */
+ public static void main(String[] args) {
+
+ ItemQueue queue = new ItemQueue();
+
+ ExecutorService executorService = Executors.newFixedThreadPool(5);
+ for (int i = 0; i < 2; i++) {
+
+ final Producer producer = new Producer("Producer_" + i, queue);
+ executorService.submit(() -> {
+ while (true) {
+ producer.produce();
+ }
+ });
+ };
+
+ for (int i = 0; i < 3; i++) {
+ final Consumer consumer = new Consumer("Consumer_" + i, queue);
+ executorService.submit(() -> {
+ while (true) {
+ consumer.consume();
+ }
+ });
+ }
+
+ executorService.shutdown();
+ try {
+ executorService.awaitTermination(10, TimeUnit.SECONDS);
+ executorService.shutdownNow();
+ } catch (InterruptedException e) {
+ System.out.println("Error waiting for ExecutorService shutdown");
+ }
+ }
+}
diff --git a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Consumer.java b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Consumer.java
new file mode 100644
index 000000000..8bb3b75b6
--- /dev/null
+++ b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Consumer.java
@@ -0,0 +1,24 @@
+package com.iluwatar.producer.consumer;
+
+/**
+ * Class responsible for consume the {@link Item} produced by {@link Producer}
+ */
+public class Consumer {
+
+ private final ItemQueue queue;
+
+ private final String name;
+
+ public Consumer(String name, ItemQueue queue) {
+ this.name = name;
+ this.queue = queue;
+ }
+
+ public void consume() throws InterruptedException {
+
+ Item item = queue.take();
+ System.out.println(String.format("Consumer [%s] consume item [%s] produced by [%s]", name,
+ item.getId(), item.getProducer()));
+
+ }
+}
diff --git a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Item.java b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Item.java
new file mode 100644
index 000000000..8d5be69a1
--- /dev/null
+++ b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Item.java
@@ -0,0 +1,27 @@
+package com.iluwatar.producer.consumer;
+
+/**
+ * Class take part of an {@link Producer}-{@link Consumer} exchange.
+ */
+public class Item {
+
+ private String producer;
+
+ private int id;
+
+ public Item(String producer, int id) {
+ this.id = id;
+ this.producer = producer;
+ }
+
+ public int getId() {
+
+ return id;
+ }
+
+ public String getProducer() {
+
+ return producer;
+ }
+
+}
diff --git a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/ItemQueue.java b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/ItemQueue.java
new file mode 100644
index 000000000..8d41fb456
--- /dev/null
+++ b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/ItemQueue.java
@@ -0,0 +1,27 @@
+package com.iluwatar.producer.consumer;
+
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * Class as a channel for {@link Producer}-{@link Consumer} exchange.
+ */
+public class ItemQueue {
+
+ private LinkedBlockingQueue- queue;
+
+ public ItemQueue() {
+
+ queue = new LinkedBlockingQueue
- (5);
+ }
+
+ public void put(Item item) throws InterruptedException {
+
+ queue.put(item);
+ }
+
+ public Item take() throws InterruptedException {
+
+ return queue.take();
+ }
+
+}
diff --git a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Producer.java b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Producer.java
new file mode 100644
index 000000000..40e71c607
--- /dev/null
+++ b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Producer.java
@@ -0,0 +1,29 @@
+package com.iluwatar.producer.consumer;
+
+import java.util.Random;
+
+/**
+ * Class responsible for producing unit of work that can be expressed as {@link Item} and submitted
+ * to queue
+ */
+public class Producer {
+
+ private final ItemQueue queue;
+
+ private final String name;
+
+ private int itemId = 0;
+
+ public Producer(String name, ItemQueue queue) {
+ this.name = name;
+ this.queue = queue;
+ }
+
+ public void produce() throws InterruptedException {
+
+ Item item = new Item(name, itemId++);
+ queue.put(item);
+ Random random = new Random();
+ Thread.sleep(random.nextInt(2000));
+ }
+}
diff --git a/producer-consumer/src/test/java/com/iluwatar/poison/pill/AppTest.java b/producer-consumer/src/test/java/com/iluwatar/poison/pill/AppTest.java
new file mode 100644
index 000000000..26b38dec0
--- /dev/null
+++ b/producer-consumer/src/test/java/com/iluwatar/poison/pill/AppTest.java
@@ -0,0 +1,20 @@
+package com.iluwatar.poison.pill;
+
+import org.junit.Test;
+
+import com.iluwatar.producer.consumer.App;
+
+/**
+ *
+ * Application test
+ *
+ */
+public class AppTest {
+
+ @Test
+ public void test() throws Exception {
+ String[] args = {};
+ App.main(args);
+
+ }
+}