You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jcs-dev@jakarta.apache.org by hc...@apache.org on 2005/01/27 11:50:57 UTC
cvs commit: jakarta-turbine-jcs/sandbox/yajcache/src/org/apache/jcs/yajcache/util/concurrent/locks KeyedReadWriteLock.java
hchar 2005/01/27 02:50:57
Added: sandbox/yajcache/src/org/apache/jcs/yajcache/util/concurrent/locks
KeyedReadWriteLock.java
Log:
read-write lock specific to a key
Revision Changes Path
1.1 jakarta-turbine-jcs/sandbox/yajcache/src/org/apache/jcs/yajcache/util/concurrent/locks/KeyedReadWriteLock.java
Index: KeyedReadWriteLock.java
===================================================================
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jcs.yajcache.util.concurrent.locks;
import java.lang.ref.ReferenceQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.jcs.yajcache.lang.ref.KeyedRefCollector;
import org.apache.jcs.yajcache.lang.ref.KeyedWeakReference;
/**
* @author Hanson Char
*/
public class KeyedReadWriteLock implements IKeyedReadWriteLock {
private final ConcurrentMap<String, KeyedWeakReference<ReadWriteLock>> rwlMap =
new ConcurrentHashMap<String, KeyedWeakReference<ReadWriteLock>>();
private final Class<? extends ReadWriteLock> rwlClass;
private final ReferenceQueue<ReadWriteLock> refQ =
new ReferenceQueue<ReadWriteLock>();
private final KeyedRefCollector collector = new KeyedRefCollector(refQ, rwlMap);
public KeyedReadWriteLock() {
this.rwlClass = ReentrantReadWriteLock.class;
}
public KeyedReadWriteLock(Class<? extends ReadWriteLock> rwlClass) {
this.rwlClass = rwlClass;
}
public Lock readLock(String key) {
return this.readWriteLock(key).readLock();
}
public Lock writeLock(String key) {
return this.readWriteLock(key).writeLock();
}
private ReadWriteLock readWriteLock(String key) {
ReadWriteLock newLock = null;
try {
newLock = 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 String key, ReadWriteLock newLock)
{
this.collector.run();
final KeyedWeakReference<ReadWriteLock> newLockRef =
new KeyedWeakReference<ReadWriteLock>(key, newLock, refQ);
KeyedWeakReference<ReadWriteLock> prevRef =
this.rwlMap.putIfAbsent(key, newLockRef);
if (prevRef == null) {
// succesfully deposited the new lock.
return newLock;
}
ReadWriteLock prev = prevRef.get();
for (; prev == null; prev=prevRef.get()) {
// Unused lock is garbage collected. So clean it up.
rwlMap.remove(key, prevRef); // remove may fail, but that's fine.
prevRef = this.rwlMap.putIfAbsent(key, newLockRef);
if (prevRef == null) {
// succesfully deposited the new lock.
return newLock;
}
// data race: someone else has just put in a lock.
}
// Return the lock deposited by another thread.
return prev;
}
// public void removeUnusedLocks() {
// this.collector.run();
// }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: turbine-jcs-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: turbine-jcs-dev-help@jakarta.apache.org