diff --git a/pom.xml b/pom.xml
index 9fa150dd4..14ac2002d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,6 +60,7 @@
intercepting-filterproducer-consumerpoison-pill
+ reader-writer-locklazy-loadingservice-layerspecification
diff --git a/reader-writer-lock/etc/reader-writer-lock.png b/reader-writer-lock/etc/reader-writer-lock.png
new file mode 100644
index 000000000..06207b502
Binary files /dev/null and b/reader-writer-lock/etc/reader-writer-lock.png differ
diff --git a/reader-writer-lock/etc/reader-writer-lock.ucls b/reader-writer-lock/etc/reader-writer-lock.ucls
new file mode 100644
index 000000000..18ffb8ccb
--- /dev/null
+++ b/reader-writer-lock/etc/reader-writer-lock.ucls
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/reader-writer-lock/index.md b/reader-writer-lock/index.md
new file mode 100644
index 000000000..75f57a4cd
--- /dev/null
+++ b/reader-writer-lock/index.md
@@ -0,0 +1,29 @@
+---
+layout: pattern
+title: Producer Consumer
+folder: reader writer lock
+permalink: /patterns/reader-writer-lock/
+categories: Concurrent
+tags:
+- Java
+---
+
+**Intent:**
+
+Suppose we have a shared memory area with the basic constraints detailed above. It is possible to protect the shared data behind a mutual exclusion mutex, in which case no two threads can access the data at the same time. However, this solution is suboptimal, because it is possible that a reader R1 might have the lock, and then another reader R2 requests access. It would be foolish for R2 to wait until R1 was done before starting its own read operation; instead, R2 should start right away. This is the motivation for the Reader Writer Lock pattern.
+
+
+
+**Applicability:**
+
+Application need to increase the performance of resource synchronize for multiple thread, in particularly there are mixed read/write operations.
+
+**Real world examples:**
+
+* [Java Reader Writer Lock](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html)
+
+**Credits**
+
+* [Readers–writer lock](https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock)
+
+* [Readers–writers_problem](https://en.wikipedia.org/wiki/Readers%E2%80%93writers_problem)
\ No newline at end of file
diff --git a/reader-writer-lock/pom.xml b/reader-writer-lock/pom.xml
new file mode 100644
index 000000000..f1553a4d1
--- /dev/null
+++ b/reader-writer-lock/pom.xml
@@ -0,0 +1,18 @@
+
+
+ 4.0.0
+
+ com.iluwatar
+ java-design-patterns
+ 1.9.0-SNAPSHOT
+
+ reader-writer-lock
+
+
+ junit
+ junit
+ test
+
+
+
diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/App.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/App.java
new file mode 100644
index 000000000..aa36ef47c
--- /dev/null
+++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/App.java
@@ -0,0 +1,82 @@
+package com.iluwatar.reader.writer.lock;
+
+import java.util.Random;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.IntStream;
+
+/**
+ * Reader writer lock is a synchronization primitive that solves one of the readers–writers
+ * problems. An RW lock allows concurrent access for read-only operations, while write operations
+ * require exclusive access.
+ *
+ * Below example use two mutexes to demonstrate the concurrent access of mutilple readers and
+ * writers.
+ *
+ */
+public class App {
+
+ private static Random ran = new Random();
+
+ /**
+ * Program entry point
+ *
+ * @param args command line args
+ */
+ public static void main(String[] args) {
+
+ ExecutorService es = Executors.newFixedThreadPool(1000);
+ ReaderWriterLock lock = new ReaderWriterLock();
+
+ AtomicInteger index = new AtomicInteger(0);
+ IntStream.range(0, 100).forEach(i -> {
+ Runnable task = null;
+ if (ran.nextFloat() <= 0.6) {
+ task = new Runnable() {
+ @Override
+ public void run() {
+ Lock writeLock = lock.writeLock();
+ writeLock.lock();
+ try {
+ int cur = index.getAndIncrement();
+ System.out.println("Writer " + cur + " begin");
+ simulateReadOrWrite();
+ System.out.println("Writer " + cur + " finish");
+ } finally {
+ writeLock.unlock();
+ }
+ }
+ };
+ } else {
+ task = new Runnable() {
+
+ @Override
+ public void run() {
+ Lock readLock = lock.readLock();
+ readLock.lock();
+ try {
+ int cur = index.getAndIncrement();
+ System.out.println("Reader " + cur + " begin");
+ simulateReadOrWrite();
+ System.out.println("Reader " + cur + " finish");
+
+ } finally {
+ readLock.unlock();
+ }
+ }
+ };
+ }
+ es.submit(task);
+ });
+
+ }
+
+ private static void simulateReadOrWrite() {
+ try {
+ Thread.sleep((long) (ran.nextFloat() * 10));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Lock.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Lock.java
new file mode 100644
index 000000000..7cbe47749
--- /dev/null
+++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Lock.java
@@ -0,0 +1,18 @@
+package com.iluwatar.reader.writer.lock;
+
+/**
+ * Lock interface
+ */
+public interface Lock {
+
+ /**
+ * Try to lock, it will wait until get the lock
+ */
+ public void lock();
+
+ /**
+ * Release lock
+ */
+ public void unlock();
+}
+
diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java
new file mode 100644
index 000000000..2d92696e3
--- /dev/null
+++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java
@@ -0,0 +1,147 @@
+package com.iluwatar.reader.writer.lock;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Class responsible for control the access for reader or writer
+ */
+public class ReaderWriterLock {
+
+ /**
+ * Mutex for reader
+ */
+ private Object r = new Object();
+
+ /**
+ * Global mutex for reader or writer, use to save the holding object
+ */
+ private Set