Concurrencey Utility: ReentrantReadWriteLock
1.5 onwards - package java.util.concurrent.locks
We have seen how to use synchronize keyword in method and in block of code. It is painstaking work that synchronizing the access of class level APIs and the object level using synchronize keyword. No guarantee of acquiring the lock in the order of thread arrived for wait queue.
JSR 166, comes with an approach which is similar to the synchronized mutual exclusive way of locking particular object. However, instead of acquiring the lock for the object (which will not allowed to access simultaneously), lock and granting work is given to the thirdparty. Means that which thread has to be allowed to access particular block of code, based on the operations(read/write).
ReentrantReadWriteLock RWL=new ReentrantReadWriteLock();
//do read operation -
//do write operation
Is this enough if we get guarantee in order of thread arrives to acquire the lock. Definitely not, we have to prioritize threads based on the business.
For instance, 100 different threads trying to access the block of code to make read only operation on the data, and waiting for the lock, now a thread comes with write operation. Will this thread will be waited long for other 100 threads to complete. No, write lock will highest priority of acquiring the lock and all other 100 threads(read lock) has to await to completion of last write lock.
Not yet, ordering of read lock is guaranteed among the threads which are awaiting for read lock. How to order this sequence ?
Fairness option is introduced in concurrency utility, if we really interested in order, we have to pass 'true' as a value for fairness.
ReentrantReadWriteLock RWL=new ReentrantReadWriteLock(true);
If fair value set to true then performance will be degraded considerablly. How to tackle this issue, either minimizing the lock required block of code or downgrading the write lock based on need basis. For instance, Write lock acquiered for 10 lines of code, where as , write operation completes in 5th line, if we keep write lock upto 10th line then other writers also needs to wait, or if no write waiting for acquiring the lock then readers also needs to be waited. In 6th(after writeoperation) line of code, read lock acquired and write lock realeased then other writers can start doing the operation. This is called Downgrading. Keep in mind in this block of code , 9th line has read operation which possibly run after all the writer threads completed :(.
Can i acquire write lock within reader block ?
No, Within the writer block, we can acquire read lock, not vice-versa.
Why do i need to use read lock ?
Obsolutely, no need of read lock if your business logic not mandates to get very latest updated value. As I mentioned above, 100 readers has to wait for 1 wirter thread. If we are not introducing this reader lock then there could be possibility that 100 readers may get different values based on the order it get executes.
In my business 500 reader and rarely writer will occur, will reader lock cause any performance issue?
Not exactly, if no writer thread found in the given point of time then reader will not be blocked. Means, multiple reader(reader threads) can read at the same time. Read lock is used for getting writer threads changes immediate affect in all other reader threads.