hchar       2005/01/31 02:33:03

  Modified:    
sandbox/yajcache/src/org/apache/jcs/yajcache/util/concurrent/locks
                        KeyedReadWriteLock.java
  Log:
  refactor + javadoc
  
  Revision  Changes    Path
  1.6       +58 -46    
jakarta-turbine-jcs/sandbox/yajcache/src/org/apache/jcs/yajcache/util/concurrent/locks/KeyedReadWriteLock.java
  
  Index: KeyedReadWriteLock.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-turbine-jcs/sandbox/yajcache/src/org/apache/jcs/yajcache/util/concurrent/locks/KeyedReadWriteLock.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- KeyedReadWriteLock.java   29 Jan 2005 13:30:57 -0000      1.5
  +++ KeyedReadWriteLock.java   31 Jan 2005 10:33:03 -0000      1.6
  @@ -40,7 +40,8 @@
   public class KeyedReadWriteLock<K> implements IKeyedReadWriteLock<K> {
       private static final boolean debug = true;
       
  -    private final @NonNullable ConcurrentMap<K, 
KeyedWeakReference<K,ReadWriteLock>> rwlMap = 
  +    private final @NonNullable 
  +            ConcurrentMap<K, KeyedWeakReference<K,ReadWriteLock>> rwlMap = 
               new ConcurrentHashMap<K, KeyedWeakReference<K,ReadWriteLock>>();
       private final @NonNullable Class<? extends ReadWriteLock> rwlClass;
       private final @NonNullable ReferenceQueue<ReadWriteLock> refQ = 
  @@ -60,81 +61,92 @@
       public KeyedReadWriteLock() {
           this.rwlClass = ReentrantReadWriteLock.class;
       }
  -    public KeyedReadWriteLock(Class<? extends ReadWriteLock> rwlClass) {
  +    public KeyedReadWriteLock(
  +            @NonNullable Class<? extends ReadWriteLock> rwlClass)
  +    {
           this.rwlClass = rwlClass;
       }
  -    public Lock readLock(K key) {
  +    public @NonNullable Lock readLock(@NonNullable final K key) {
           if (debug)
               this.countReadLock.incrementAndGet();
           return this.readWriteLock(key).readLock();
       }
  -    public Lock writeLock(K key) {
  +    public @NonNullable Lock writeLock(@NonNullable final K key) {
           if (debug)
               this.countWriteLock.incrementAndGet();
           return this.readWriteLock(key).writeLock();
       }
  -    private ReadWriteLock readWriteLock(K key) {
  +    private @NonNullable ReadWriteLock readWriteLock(@NonNullable final K 
key) {
           this.collector.run();
  -        KeyedWeakReference<K,ReadWriteLock> prevRef = this.rwlMap.get(key);
  -        
  -        if (prevRef != null) {
  -            // existing lock may exist
  -            if (debug)
  -                this.countKeyHit.incrementAndGet();
  -            ReadWriteLock prev = prevRef.get();
  -            
  -            if (prev != null) {
  -                // existing lock
  -                if (debug)
  -                    this.countLockExist.incrementAndGet();
  -                return prev;
  -            }
  +        ReadWriteLock ret = this.getExistingLock(key);
  +        return ret == null ? this.tryNewLock(key) : ret;
  +    }
  +    /** 
  +     * Returns an existing RWLock for the specified key, or null if not 
found. 
  +     */
  +    private ReadWriteLock getExistingLock(@NonNullable final K key) {
  +        KeyedWeakReference<K,ReadWriteLock> ref = this.rwlMap.get(key);
  +        return ref == null ? null : this.toLock(ref);
  +    }
  +    /**
  +     * Returns the RWLock of the given RWLock weak reference, cleaning up
  +     * stale reference as necessary should the RWLock be garbage collected.
  +     */
  +    private ReadWriteLock toLock(
  +            @NonNullable KeyedWeakReference<K,ReadWriteLock> ref)
  +    {
  +        // existing lock may exist
  +        if (debug)
  +            this.countKeyHit.incrementAndGet();
  +        ReadWriteLock prev = ref.get();
  +
  +        if (prev != null) {
  +            // existing lock
               if (debug)
  -                this.countLockRefEmpty.incrementAndGet();
  -            // stale reference; doesn't matter if fail
  -            this.rwlMap.remove(key,  prevRef);
  +                this.countLockExist.incrementAndGet();
  +            return prev;
           }
  -        // Instantiate a new RW lock.
  -        ReadWriteLock newLock = null;
  +        if (debug)
  +            this.countLockRefEmpty.incrementAndGet();
  +        // stale reference; doesn't matter if fail
  +        this.rwlMap.remove(ref.getKey(),  ref);
  +        return null;
  +    }
  +    /** Instantiate a new RW lock. */
  +    private @NonNullable ReadWriteLock createRWLock() {
  +        if (debug)
  +            this.countRWLockCreate.incrementAndGet();
           try {
  -            newLock = rwlClass.newInstance();
  -            if (debug)
  -                this.countRWLockCreate.incrementAndGet();
  +            return rwlClass.newInstance();
           } catch(IllegalAccessException ex) {
               throw new RuntimeException(ex);
           } catch(InstantiationException ex) {
               throw new RuntimeException(ex);
           }
  -        return this.getLock(key, newLock);
       }
  -    private ReadWriteLock getLock(final K key, ReadWriteLock newLock) 
  +    /**
  +     * Returns either a new lock created by the executing thread;
  +     * or an existing lock created by another thread due to data race.
  +     */
  +    private @NonNullable ReadWriteLock tryNewLock(@NonNullable final K key)
       {
  +        final ReadWriteLock newLock = this.createRWLock();
           final KeyedWeakReference<K,ReadWriteLock> newLockRef = 
                   new KeyedWeakReference<K,ReadWriteLock>(key, newLock, refQ);
  -        ReadWriteLock prev = null;
  -        KeyedWeakReference<K,ReadWriteLock> prevRef = null;
           do {
  -            prevRef = this.rwlMap.putIfAbsent(key, newLockRef);
  -
  -            if (prevRef == null) {
  -                // succesfully deposited the new lock.
  +            KeyedWeakReference<K,ReadWriteLock> ref = 
  +                    this.rwlMap.putIfAbsent(key, newLockRef);
  +            if (ref == null) {
  +                // successfully deposited the new lock.
                   if (debug)
                       this.countLockNew.incrementAndGet();
                   return newLock;
               }
  -            // existing lock may exist
  -            prev = prevRef.get();
  +            ReadWriteLock rwl = this.toLock(ref);
               
  -            if (prev != null) {
  -                // exist lock
  -                if (debug)
  -                    this.countLockExist.incrementAndGet();
  -                return prev;
  +            if (rwl != null) {
  +                return rwl;
               }
  -            // stale reference; doesn't matter if fail
  -            if (debug)
  -                this.countLockRefEmpty.incrementAndGet();
  -            this.rwlMap.remove(key,  prevRef);
           } while(true);
       }
       @Override public String toString() {
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to