Home » Java

Implicit & Explicit Locks

23 November 2008 10,104 views No Comment

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.

Pages: 1 2 3 4

Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.