This class is similar to PreferredWriterReadWriteLock except that the read lock is upgradable to write lock. I.e., when a user calls upgradeLock(), it will release the read lock, wait for all the read locks to clear and obtain a write lock afterwards. In particular, the write lock is obtained with priority to prevent deadlock situation. The current design is based in part from Doug Lea's PreferredWriterReadWriteLock.
Note that the pre-requisite to use upgrade lock is the pre-existing of a read lock. Otherwise, a RuntimeException will be thrown.
Also note that currently lock can only be obtained through attempt
api with specified timeout instead acquire
is not supported.
Internally, the upgrade is done through a Semaphore where a thread with a higher priority will obtain the write lock first. The following scenarios then can happen:
- If there are multiple read locks granted (and no write lock request in waiting), an upgrade will release one read lock (decrease the counter), bump up upagrade counter, increase the current thread priority, set a thread local as upgrade thread, and place a write lock acquire() call. Upon waken up, it will check if the current thread is an upgrade. If it is, restore the thread priority, and decrease the upgrade counter.
- If there are mutiple write locks request in waiting (and only one read lock granted), decrease the read lock counter, bump up the upgrade counter, and increase the current thread priority. When one of the writer gets wake up, it will first check if upgrade counter is zero. If not, it will first release the semaphore so the upgrade thread can grab it, check the semaphore is gone, do notify, and issue myself another acquire to grab the nextInterceptor available semaphore.
@author Ben Wang