I have a set of wrapped ReentrantLocks
that have unique integer ids, where I require threads to acquire lower-id locks before they acquire higher-id locks in order to prevent deadlock. Three of the locks (lock0, lock1, and lock2) have greater priority than the locks with higher ids, while all of the other locks have the same priority - this means that if a thread acquires one of these three high-priority locks then they need to interrupt the other threads that are holding on to the necessary low-priority locks. For example, Thread1 is holding on to lock4 and lock5, and Thread0 is holding on to lock0 and needs lock4 and lock5, so Thread0 interrupts Thread1 (which acquired its locks using lockInterruptibly
and which occasionally queries its isInterrupted
method) and takes its locks. Thread1 waits until signaled by Thread0 (i.e. it doesn't try to reacquire the locks until Thread0 is finished with them).
This isn't ideal for several reasons. Ideally I'd like Thread0 to immediately signal that it wants the lock so that other threads don't jump ahead and acquire the lock while Thread1 is taking care of interrupting Thread0 (i.e. Thread0 goes on the queue of waiting threads so that if Thread2 tries to acquire the lock while Thread0 is interrupting Thread1 then Thread0 will still get the lock before Thread2) - e.g. I'd like a tryLock
variant that adds the thread to the lock's queue if another thread is holding the lock. Also, at present if there are threads queued on lock4 or lock5 then Thread0 has to wait for them to acquire the lock and then interrupt them - it would be better if Thread0 could empty the waiting queue on the locks (assuming that none of the waiting threads held high-priority locks). Finally, it isn't necessary for Thread1 to give up all of its locks: in the case that Thread0 wants lock0 and lock5 while Thread1 wants lock4 and lock5, then Thread1 need not give up its lock on lock4, but lockInterruptibly
will cause the thread to give up all of its locks when interrupted (assuming that the thread was interrupted while waiting to acquire a lock).
Before I reinvent the wheel, I was wondering if there was a lock class that already implemented some/all of these requirements, some sort of PriorityReentrantLock
or whatever. I've looked at the AbstractQueuedSynchronizer
and I don't think it wouldn't require too much work on my part to modify it to meet my needs (especially since I only need two priorities), but the less new code I need to test the better.