Skip to content

Commit 3731d26

Browse files
committed
implants the iluwatar#75 reader writer lock
1 parent a015182 commit 3731d26

9 files changed

Lines changed: 409 additions & 0 deletions

File tree

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
<module>intercepting-filter</module>
6161
<module>producer-consumer</module>
6262
<module>poison-pill</module>
63+
<module>reader-writer-lock</module>
6364
<module>lazy-loading</module>
6465
<module>service-layer</module>
6566
<module>specification</module>
36.7 KB
Loading
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<class-diagram version="1.1.8" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"
3+
realizations="true" associations="true" dependencies="false" nesting-relationships="true">
4+
<class id="1" language="java" name="com.iluwatar.reader.writer.lock.ReaderWriterLock.ReaderLock"
5+
project="reader-writer-lock"
6+
file="/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java" binary="false"
7+
corner="BOTTOM_RIGHT">
8+
<position height="-1" width="-1" x="305" y="511"/>
9+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
10+
sort-features="false" accessors="true" visibility="true">
11+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
12+
<operations public="true" package="true" protected="true" private="true" static="true"/>
13+
</display>
14+
</class>
15+
<class id="2" language="java" name="com.iluwatar.reader.writer.lock.ReaderWriterLock" project="reader-writer-lock"
16+
file="/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java" binary="false"
17+
corner="BOTTOM_RIGHT">
18+
<position height="-1" width="-1" x="394" y="270"/>
19+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
20+
sort-features="false" accessors="true" visibility="true">
21+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
22+
<operations public="true" package="true" protected="true" private="true" static="true"/>
23+
</display>
24+
</class>
25+
<class id="3" language="java" name="com.iluwatar.reader.writer.lock.App" project="reader-writer-lock"
26+
file="/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/App.java" binary="false"
27+
corner="BOTTOM_RIGHT">
28+
<position height="-1" width="-1" x="671" y="274"/>
29+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
30+
sort-features="false" accessors="true" visibility="true">
31+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
32+
<operations public="true" package="true" protected="true" private="true" static="true"/>
33+
</display>
34+
</class>
35+
<interface id="4" language="java" name="com.iluwatar.reader.writer.lock.Lock" project="reader-writer-lock"
36+
file="/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Lock.java" binary="false"
37+
corner="BOTTOM_RIGHT">
38+
<position height="101" width="148" x="322" y="597"/>
39+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
40+
sort-features="false" accessors="true" visibility="true">
41+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
42+
<operations public="true" package="true" protected="true" private="true" static="true"/>
43+
</display>
44+
</interface>
45+
<class id="5" language="java" name="com.iluwatar.reader.writer.lock.ReaderWriterLock.WriterLock"
46+
project="reader-writer-lock"
47+
file="/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java" binary="false"
48+
corner="BOTTOM_RIGHT">
49+
<position height="-1" width="-1" x="488" y="509"/>
50+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
51+
sort-features="false" accessors="true" visibility="true">
52+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
53+
<operations public="true" package="true" protected="true" private="true" static="true"/>
54+
</display>
55+
</class>
56+
<nesting id="6">
57+
<end type="SOURCE" refId="2"/>
58+
<end type="TARGET" refId="5"/>
59+
</nesting>
60+
<realization id="7">
61+
<end type="SOURCE" refId="5"/>
62+
<end type="TARGET" refId="4"/>
63+
</realization>
64+
<realization id="8">
65+
<end type="SOURCE" refId="1"/>
66+
<end type="TARGET" refId="4"/>
67+
</realization>
68+
<association id="9">
69+
<end type="SOURCE" refId="2" navigable="false">
70+
<attribute id="10" name="writeLock"/>
71+
<multiplicity id="11" minimum="0" maximum="1"/>
72+
</end>
73+
<end type="TARGET" refId="5" navigable="true"/>
74+
<display labels="true" multiplicity="true"/>
75+
</association>
76+
<association id="12">
77+
<end type="SOURCE" refId="2" navigable="false">
78+
<attribute id="13" name="readLock"/>
79+
<multiplicity id="14" minimum="0" maximum="1"/>
80+
</end>
81+
<end type="TARGET" refId="1" navigable="true"/>
82+
<display labels="true" multiplicity="true"/>
83+
</association>
84+
<nesting id="15">
85+
<end type="SOURCE" refId="2"/>
86+
<end type="TARGET" refId="1"/>
87+
</nesting>
88+
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
89+
sort-features="false" accessors="true" visibility="true">
90+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
91+
<operations public="true" package="true" protected="true" private="true" static="true"/>
92+
</classifier-display>
93+
<association-display labels="true" multiplicity="true"/>
94+
</class-diagram>

reader-writer-lock/index.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
layout: pattern
3+
title: Producer Consumer
4+
folder: reader writer lock
5+
permalink: /patterns/reader-writer-lock/
6+
categories: Concurrent
7+
tags:
8+
- Java
9+
---
10+
11+
**Intent:**
12+
13+
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.
14+
15+
![alt text](./etc/reader-writer-lock.png "Reader writer lock")
16+
17+
**Applicability:**
18+
19+
Application need to increase the performance of resource synchronize for multiple thread, in particularly there are mixed read/write operations.
20+
21+
**Real world examples:**
22+
23+
* [Java Reader Writer Lock](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html)
24+
25+
**Credits**
26+
27+
* [Readers–writer lock](https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock)
28+
29+
* [Readers–writers_problem](https://en.wikipedia.org/wiki/Readers%E2%80%93writers_problem)

reader-writer-lock/pom.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0"?>
2+
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>com.iluwatar</groupId>
7+
<artifactId>java-design-patterns</artifactId>
8+
<version>1.9.0-SNAPSHOT</version>
9+
</parent>
10+
<artifactId>reader-writer-lock</artifactId>
11+
<dependencies>
12+
<dependency>
13+
<groupId>junit</groupId>
14+
<artifactId>junit</artifactId>
15+
<scope>test</scope>
16+
</dependency>
17+
</dependencies>
18+
</project>
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.iluwatar.reader.writer.lock;
2+
3+
import java.util.Random;
4+
import java.util.concurrent.ExecutorService;
5+
import java.util.concurrent.Executors;
6+
import java.util.concurrent.atomic.AtomicInteger;
7+
import java.util.stream.IntStream;
8+
9+
/**
10+
* Reader writer lock is a synchronization primitive that solves one of the readers–writers
11+
* problems. An RW lock allows concurrent access for read-only operations, while write operations
12+
* require exclusive access.
13+
* <p>
14+
* Below example use two mutexes to demonstrate the concurrent access of mutilple readers and
15+
* writers.
16+
*
17+
*/
18+
public class App {
19+
20+
private static Random ran = new Random();
21+
22+
/**
23+
* Program entry point
24+
*
25+
* @param args command line args
26+
*/
27+
public static void main(String[] args) {
28+
29+
ExecutorService es = Executors.newFixedThreadPool(1000);
30+
ReaderWriterLock lock = new ReaderWriterLock();
31+
32+
AtomicInteger index = new AtomicInteger(0);
33+
IntStream.range(0, 100).forEach(i -> {
34+
Runnable task = null;
35+
if (ran.nextFloat() <= 0.6) {
36+
task = new Runnable() {
37+
@Override
38+
public void run() {
39+
Lock writeLock = lock.writeLock();
40+
writeLock.lock();
41+
try {
42+
int cur = index.getAndIncrement();
43+
System.out.println("Writer " + cur + " begin");
44+
simulateReadOrWrite();
45+
System.out.println("Writer " + cur + " finish");
46+
} finally {
47+
writeLock.unlock();
48+
}
49+
}
50+
};
51+
} else {
52+
task = new Runnable() {
53+
54+
@Override
55+
public void run() {
56+
Lock readLock = lock.readLock();
57+
readLock.lock();
58+
try {
59+
int cur = index.getAndIncrement();
60+
System.out.println("Reader " + cur + " begin");
61+
simulateReadOrWrite();
62+
System.out.println("Reader " + cur + " finish");
63+
64+
} finally {
65+
readLock.unlock();
66+
}
67+
}
68+
};
69+
}
70+
es.submit(task);
71+
});
72+
73+
}
74+
75+
private static void simulateReadOrWrite() {
76+
try {
77+
Thread.sleep((long) (ran.nextFloat() * 10));
78+
} catch (InterruptedException e) {
79+
e.printStackTrace();
80+
}
81+
}
82+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.iluwatar.reader.writer.lock;
2+
3+
/**
4+
* Lock interface
5+
*/
6+
public interface Lock {
7+
8+
/**
9+
* Try to lock, it will wait until get the lock
10+
*/
11+
public void lock();
12+
13+
/**
14+
* Release lock
15+
*/
16+
public void unlock();
17+
}
18+

0 commit comments

Comments
 (0)