Managing multiple locks

前端 未结 2 1052
庸人自扰
庸人自扰 2021-01-16 06:07

I have the following situation: I\'m concurrently processing requests that have a given key. I can process any number of requests at the same time, as long as each key in pr

2条回答
  •  春和景丽
    2021-01-16 06:52

    Following solution does not locks LockMap and so is extremly parallel. It uses custom-made Locks to track the moment when they can be deleted, and handles concurrent deletion/creation.

    class Lock {
        boolean busy=true; // locked state, a thread is working
        int waitCount=0; // number of waiting threads
    
            /** returns true if lock succeeded */
        synchronized boolean tryLock() throws InterruptedException {
            if (busy) {
                waitCount++; 
            } else if (waitCount==0){
                    // such values mean that the lock is deleted
                return false;
            } else {
                busy=true;
                return true;
            }
            for (;;) {
                wait();
                if (!busy) {
                    waitCount--;
                    busy=true;
                    return true;
                }
            }
        }
    
    }
    
    class LockMap {
        private ConcurrentHashMap locks = new ConcurrentHashMap<>();
    
        void acquireLock(K key) throws InterruptedException {
            for (;;) {
                Lock lockObj = locks.get(key);
                if (lockObj==null) {
                    Lock myLockObj = new Lock();
                    lockObj=locks.putIfAbsent(key, myLockObj);
                    if (lockObj==null) {
                        // successfully inserted, and so locked
                        return;
                    }
                }
                // lockObj existed, lock it or wait in queue
                if (lockObj.tryLock()) {
                    return;
                }
            }
        }
    
        void releaseLock(K key) {
            Lock lockObj = locks.get(key);
            synchronized (lockObj) {
                lockObj.busy=false;
                if (lockObj.waitCount==0) {
                    locks.remove(key);
                } else {
                    lockObj.notify();
                }
            }
        }
    }
    

提交回复
热议问题