Search code examples
javalocksreentrantlock

Unlocking lock owned by another thread java


I have a LockManager that manages the locks of several threads. Sometimes the threads are bad boys, and I have to kill them and ask the LockManager to release all their locks. However, since I use ReentrantLock in java this is impossible, I can not unlock a lock owned by another thread.

I am forced to use Locks (cannot use semaphores, it is point of the homework). Is there any Java Lock implementation that allows me to unlock locks owned by other threads?

So far the options I considered are:

  • re-implementing ReentrantLock in a way that allows me to do this
  • Make some sort of mapping between Semaphores and ReentrantLocks

Extra Sources you may find useful:


Solution

  • Would you be allowed to use your own Lock? Here's a class that completely proxies the Lock but when it is told to force the unlock it merely replaces the lock it is proxying with a new one. This should have the effect you want. Sadly it still does not deal with the locks that are left dangling but that now becomes somebody else's problem. Your locks are now magically unlocked.

    static class LockProxy<L extends Lock> implements Lock {
    
        // The actual lock.
        private volatile Lock lock;
    
        public LockProxy(L lock) {
            // Trap the lock we are proxying.
            this.lock = lock;
        }
    
        @Override
        public void lock() {
            // Proxy it.
            lock.lock();
        }
    
        @Override
        public void lockInterruptibly() throws InterruptedException {
            // Proxy it.
            lock.lockInterruptibly();
        }
    
        @Override
        public boolean tryLock() {
            // Proxy it.
            return lock.tryLock();
        }
    
        @Override
        public boolean tryLock(long l, TimeUnit tu) throws InterruptedException {
            // Proxy it.
            return lock.tryLock(l, tu);
        }
    
        @Override
        public void unlock() {
            // Proxy it.
            lock.unlock();
        }
    
        @Override
        public Condition newCondition() {
            // Proxy it.
            return lock.newCondition();
        }
    
        // Extra functionality to unlock from any thread.
        public void forceUnlock() {
            // Actually just replace the perhaps locked lock with a new one.
            // Kinda like a clone. I expect a neater way is around somewhere.
            if (lock instanceof ReentrantLock) {
                lock = new ReentrantLock();
            } else {
                throw new UnsupportedOperationException(
                    "Cannot force unlock of lock type "
                        + lock.getClass().getSimpleName());
            }
        }
    }