Implicit & Explicit Locks
Explicit Read-Write Locks
Explicit locks can be accessed in two ways. A read access is granted to a thread that wants to read values from a critical section or a gaurded resource. While only a single thread at a time (a writer thread) can modify the shared data, in many cases any number of threads can concurrently read the data (hence reader threads). In theory, the increase in concurrency permitted by the use of a read-write lock will lead to performance improvements over the use of a mutual exclusion lock.
To demonstrate Read-Write locks, we enhance the producer-consumer solution above with a reporting thread. The new class is called ExplicitReadWriteLocksDemo. The reporting thread reports on the shared buffer and prints out the state of the buffer continuously. So at any point in time we can see what item was put in the shared buffer and when the buffer is empty, we know that a consumer removed the item. We add a new method to Drop class which the reporting thread calls:
137 138 139 140 141 142 143 144 145 146 147 148 149 | public String report() { try { readLock.lock(); if (shared.isEmpty()) { return "Empty!"; } return shared.get(0); } finally { readLock.unlock(); } } |
The reporting thread looks like so:
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | static class Reporter implements Runnable { private String name; private Drop drop; private Flag aFlag; public Reporter(String name, Drop drop, Flag aFlag) { this.name = name; this.drop = drop; this.aFlag = aFlag; } public void run() { String previousMessage = ""; while (aFlag.isConsumerRunning()) { String newMessage = drop.report(); if (!newMessage.equals(previousMessage)) { System.err.println(" " + name + " " + newMessage); previousMessage = newMessage; } } } } |
The new thread also shares the drop instance like so:
25 26 27 28 29 30 31 32 33 34 35 | public static void main(String s[]) { Flag aFlag = new Flag(); Drop drop = new Drop(); Consumer c1 = new Consumer("C1", drop, aFlag); Producer p1 = new Producer("P1", drop); Reporter r1 = new Reporter("R1", drop, aFlag); (new Thread(p1)).start(); (new Thread(c1)).start(); (new Thread(r1)).start(); } |
The output looks something like this: R1 Empty! P1 produced: Let's use guarded C1 received: Let's use guarded C1 received: blocks to create a P1 produced: blocks to create a P1 produced: Producer-Consumer C1 received: Producer-Consumer P1 produced: application. This R1 application. This R1 Empty! C1 received: application. This C1 received: kind of application P1 produced: kind of application R1 shares data between two P1 produced: shares data between two R1 Empty! C1 received: shares data between two
As the reporting thread doesn’t wait on any condition, and has a read access, it shows when the buffer is empty.









Leave your response!