Как я могу преобразовать ReentrantReadWriteLock.readLock или ReentrantReadWriteLock.writeLock в мои объекты класса - PullRequest
1 голос
/ 30 ноября 2011

То, что я пытаюсь сделать, это получить количество повторных подсчетов, удерживаемых текущим потоком за один раз. Я написал обертку для этого, но моя проблема в том, что метод ReadLock () возвращает ReentrantReadWriteLock.WriteLock, поэтому у меня нетПосле этого нужно получить избыточный метод getThreadReadLockCount. Я хочу, чтобы метод readLock () возвращал меня, чтобы у меня был избыток метода count.Anyideas.?

   private final ThreadLocal    readLocksHeldByThread;

private static class ReadCounts {
    public int  value   = 0;
}

public CustomReentrantReadWriteLock() {
    super(true);
    readLocksHeldByThread = new ThreadLocal() {
        @Override
        public Object initialValue() {
            return new ReadCounts();
        }
    };
}

@Override
public synchronized ReadLock readLock() {
    final ReadCounts myReadLocks = (ReadCounts) readLocksHeldByThread.get();
    ++myReadLocks.value;
    return super.readLock();
}

    public synchronized int getThreadReadLockCount() {
    final ReadCounts currentReadLocks = (ReadCounts) readLocksHeldByThread.get();
    return currentReadLocks.value;
}

1 Ответ

1 голос
/ 30 ноября 2011

ваш код только подсчитывает, сколько раз поток запрашивал блокировку на чтение, если он кэшируется между блокировкой и освобождением, это даст разные результаты:

Lock rl = var.readLock();
rl.lock();
try{
    //...
}finally{
    rl.unlock();
}

против

var.readLock().lock();
try{
    //...
}finally{
    var.readLock().unlock();
}

будетдать разные результаты

вы можете обернуть возвращенную блокировку примерно так

@Override public Lock readLock() {
     final ReadCounts myReadLocks = (ReadCounts) readLocksHeldByThread.get();
     return new Lock(){
        Lock l = super.readLock(); 
        public void lock(){
            l.lock();
            ++myReadLocks.value;
        }

        public void lockInterruptibly() throws InterruptedException{
            l.lockInterruptibly();
            ++myReadLocks.value;
        }

        public boolean tryLock(){
            if(l.tryLock()){
                ++myReadLocks.value;
                return true;
            }else return false;
        }

        public boolean tryLock(long time, TimeUnit unit) throws InterruptedException{
            if(l.tryLock(time,unit)){
                ++myReadLocks.value;
                return true;
            }else return false;
        }

        public void unlock(){
            --myReadLocks.value;
            l.unlock();
        }

        public Condition newCondition(){
            return l.newCondition();
        }

     }
} 
...