- Requires a multi-processor system
- The frequency of reads as compared to that of writes. A higher frequency of reads is more suitable.
- Duration of reads as compared to that of writes. Read duration has to be longer, as short reads mean that the readLock will become an overhead.
- Contention for the data, i.e. the number of threads that will try to read or write the data at the same time
The following are a few issues to be considered while creating a ReadWriteLock
- Whether to grant the read lock or the write lock the priority.
- Whether readers that request the read lock while a reader is active and a writer is waiting.
- Whether the locks are reentrant.
- Can the write lock be downgraded to a read lock without allowing an intervening writer?
- Can a read lock be upgraded to a write lock, in preference to other waiting readers or writers?
- Acquisition order: Does not impose a reader or writer preference ordering for lock access.
- When constructed as fair, threads contend for entry using an approximately arrival-order policy.
- When the write lock is released either the longest-waiting single writer will be assigned the write lock, or if there is a reader waiting longer than any writer, the set of readers will be assigned the read lock.
- if readers are active and a writer enters the lock then no subsequent readers will be granted the read lock until after that writer has acquired and released the write lock.
- Reentrancy: Allows both readers and writers to reacquire read or write locks in the style of a ReentrantLock. A writer can acquire the read lock - but not vice-versa. If a reader tries to acquire the write lock it will never succeed.
- Interruption of lock acquisition: The read lock and write lock both support interruption during lock acquisition.
- Condition support: The write lock provides a Condition implementation that behaves in the same way, with respect to the write lock, as the one provided by ReentrantLock.newCondition(). The read lock does not support a Condition.
- Instrumentation: Supports methods to determine whether locks are held or contended.
public class Data {
private List<String> names;
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public Data() {
names = new ArrayList<String>();
}
public List<String> getNames() {
return names;
}
public void setNames(List<String> names) {
this.names = names;
}
public void add(String str) {
lock.writeLock().lock();
System.out.println("Writer: Number of threads waiting : " + lock.getQueueLength());
// This will alwas be 1.
System.out.println("Writer: Number of write locks waiting : " + lock.getWriteHoldCount());
names.add(str);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.writeLock().unlock();
}
public void readData() {
lock.readLock().lock();
System.out.println("Reader: Number of threads waiting : " + lock.getQueueLength());
System.out.println("Reader: Number of read locks : " + lock.getReadLockCount());
Iterator<String> iter = names.iterator();
while (iter.hasNext()) {
iter.next();
// System.out.println(iter.next());
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.readLock().unlock();
}
}
public class ListReader implements Runnable {
Data myData;
public void run() {
for(int i = 0; i < 10; i++) {
myData.readData();
}
}
public ListReader(Data myData) {
super();
this.myData = myData;
}
}
public class ListWriter implements Runnable {
Data myData;
public ListWriter(Data myData) {
super();
this.myData = myData;
}
public void run() {
for(int i = 0; i < 10; i++) {
myData.add(Thread.currentThread().getName() + " : " + i);
}
}
}
public static void main(String[] args) {
ListReader[] readers = new ListReader[THREADS];
ListWriter[] writers = new ListWriter[THREADS];
Data data = new Data();
Thread[] threads = new Thread[THREADS * 2];
for (int i = 0; i < THREADS; i++) {
readers[i] = new ListReader(data);
writers[i] = new ListWriter(data);
threads[i] = new Thread(readers[i], "" + i);
threads[i + THREADS] = new Thread(writers[i], "" + i);
}
for (int i = 0; i < THREADS * 2; i++) {
threads[i].start();
}
for (int i = 0; i < THREADS * 2; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
No comments:
Post a Comment