1) Reader&Writer Problem Intro
? ? 1> Reader&Writer task may share a resource, say a DB.
? ? 2> Many Reader may access a DB without fear of data corruption.
? ? 3> Only one Writer may access a DB at a time.
? ? Read Access: If no threads are writing, and no threads have acquired the write access.
? ? Write Access: If no threads are reading or writing.
?
2) Read&Write Lock
? ? 1> Read&Write Lock is especially useful for Reader&Writer Problem
? ? ? ? ?when there are many threads that read from a data structure and fewer threads that modify it.?
? ? 2> It makes sense to allow shared access for the readers. And a writer must still have exclusive access.
?
3) Example
class="java">package edu.xmu.thread;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
public class ReadeWriteLockTest {
public static void main(String[] args) {
Calculator calculator = new Calculator(2);
Thread reader = new Thread(new Reader(calculator));
Thread reader2 = new Thread(new Reader(calculator));
Thread writer = new Thread(new Writer(calculator));
reader.start();
reader2.start();
writer.start();
}
}
class Reader implements Runnable {
Calculator calculator;
public Reader(Calculator calculator) {
super();
this.calculator = calculator;
}
@Override
public void run() {
while (true) {
int sum = calculator.getSum();
System.out.println("Thread: " + Thread.currentThread()
+ " finished getSum(), sum = " + sum);
try {
Thread.sleep((long) (1000 * Math.random()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Writer implements Runnable {
Calculator calculator;
public Writer(Calculator calculator) {
super();
this.calculator = calculator;
}
@Override
public void run() {
while (true) {
calculator.add((int) (10 * Math.random()));
try {
Thread.sleep((long) (1000 * Math.random()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Calculator {
ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
ReadLock readLock;
WriteLock writeLock;
int sum;
public Calculator(int sum) {
super();
this.sum = sum;
readLock = readWriteLock.readLock();
writeLock = readWriteLock.writeLock();
}
public void add(int i) {
writeLock.lock();
System.out.println("Thread: " + Thread.currentThread()
+ " get into add(" + i + ")");
try {
Thread.sleep((long) (1000 * Math.random()));
} catch (InterruptedException e) {
e.printStackTrace();
}
sum += i;
System.out.println("Thread: " + Thread.currentThread()
+ " finished add(" + i + ")");
writeLock.unlock();
}
public int getSum() {
readLock.lock();
System.out.println("Thread: " + Thread.currentThread()
+ " get into getSum()");
readLock.unlock();
return sum;
}
}
? ? Output:
Thread: Thread[Thread-0,5,main] get into getSum() // thread-0 got read lock Thread: Thread[Thread-1,5,main] get into getSum() // thread-1 got read lock Thread: Thread[Thread-0,5,main] finished getSum(), sum = 2 // thread-0 released read lock Thread: Thread[Thread-1,5,main] finished getSum(), sum = 2 // thread-1 released read lock Thread: Thread[Thread-2,5,main] get into add(4) // thread-2 got write lock and no other write/read lock may be got before this write lock released Thread: Thread[Thread-2,5,main] finished add(4) // thread-2 released write lock and other write/read lock may be got again. Thread: Thread[Thread-1,5,main] get into getSum() Thread: Thread[Thread-0,5,main] get into getSum() Thread: Thread[Thread-1,5,main] finished getSum(), sum = 6 Thread: Thread[Thread-0,5,main] finished getSum(), sum = 6 Thread: Thread[Thread-1,5,main] get into getSum() Thread: Thread[Thread-1,5,main] finished getSum(), sum = 6 Thread: Thread[Thread-2,5,main] get into add(5) Thread: Thread[Thread-2,5,main] finished add(5) Thread: Thread[Thread-0,5,main] get into getSum() Thread: Thread[Thread-1,5,main] get into getSum() Thread: Thread[Thread-0,5,main] finished getSum(), sum = 11 Thread: Thread[Thread-1,5,main] finished getSum(), sum = 11 Thread: Thread[Thread-0,5,main] get into getSum() Thread: Thread[Thread-0,5,main] finished getSum(), sum = 11 Thread: Thread[Thread-2,5,main] get into add(1) Thread: Thread[Thread-2,5,main] finished add(1) Thread: Thread[Thread-1,5,main] get into getSum() Thread: Thread[Thread-1,5,main] finished getSum(), sum = 12 Thread: Thread[Thread-2,5,main] get into add(6) Thread: Thread[Thread-2,5,main] finished add(6) Thread: Thread[Thread-0,5,main] get into getSum() Thread: Thread[Thread-0,5,main] finished getSum(), sum = 18
?
?
Reference Links:
1)?http://www.cs.wustl.edu/~fredk/Courses/cs422/sp03/Lectures/concurrency2.pdf
2)?http://tutorials.jenkov.com/java-concurrency/read-write-locks.html
3)?http://java.dzone.com/news/java-concurrency-read-write-lo
?
?