You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wink.apache.org by bl...@apache.org on 2009/09/17 18:04:00 UTC
svn commit: r816250 -
/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/SoftConcurrentMap.java
Author: bluk
Date: Thu Sep 17 16:04:00 2009
New Revision: 816250
URL: http://svn.apache.org/viewvc?rev=816250&view=rev
Log:
Volatile copy on write map for SoftConcurrentMap
Thanks to Doug Larson for the suggestion and
profiling work.
See [WINK-190]
Modified:
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/SoftConcurrentMap.java
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/SoftConcurrentMap.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/SoftConcurrentMap.java?rev=816250&r1=816249&r2=816250&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/SoftConcurrentMap.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/SoftConcurrentMap.java Thu Sep 17 16:04:00 2009
@@ -21,9 +21,6 @@
import java.lang.ref.SoftReference;
import java.util.Map;
import java.util.WeakHashMap;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Concurrent implementation of the SimpleMap interface. This implementation is
@@ -32,42 +29,35 @@
* <p>
* Pay attention that put value always returns the current value and not the
* original value. It was done to allow the following code pattern:
+ *
* <pre>
- * SoftConcurrentMap<K, V> cache = new SoftConcurrentMap<K, V>();
+ * SoftConcurrentMap<K, V> cache = new SoftConcurrentMap<K, V>();
* V cached = cache.get(key);
- * return cached =! null ? cached : cache.put(createValue());
- * </pre>
+ * return cached = !null ? cached : cache.put(createValue());
+ * </pre>
+ *
* @param <K>
* @param <V>
*/
public class SoftConcurrentMap<K, V> implements SimpleMap<K, V> {
- private final Lock readersLock;
- private final Lock writersLock;
- private final Map<K, SoftReference<V>> map;
+ /*
+ * Note that this volatile variable is important for publication purposes.
+ */
+ private volatile Map<K, SoftReference<V>> map;
/**
- * Provides the map implementation. Pay attention that get method is
- * synchronized using the read lock, therefore it must not change the entire
- * collection.
+ * Provides the map implementation.
*
* @param map
*/
public SoftConcurrentMap() {
this.map = new WeakHashMap<K, SoftReference<V>>();
- ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
- readersLock = readWriteLock.readLock();
- writersLock = readWriteLock.writeLock();
}
public V get(K key) {
- readersLock.lock();
- try {
- SoftReference<V> softReference = map.get(key);
- return softReference != null ? softReference.get() : null;
- } finally {
- readersLock.unlock();
- }
+ SoftReference<V> softReference = map.get(key);
+ return softReference != null ? softReference.get() : null;
}
/**
@@ -77,26 +67,25 @@
* <p>
* Unlike the regular Map.put method, this method returns the current value
* and not the previous value.
+ * <p>
+ * Note that a copy on write pattern is used where the existing cache is
+ * treated as a read only cache and then it is copied to a new cache.
*
* @return val - the current value.
*/
- public V put(K key, V val) {
- writersLock.lock();
- try {
- map.put(key, new SoftReference<V>(val));
- return val;
- } finally {
- writersLock.unlock();
- }
+ public synchronized V put(K key, V val) {
+ WeakHashMap<K, SoftReference<V>> copyOfMap = new WeakHashMap<K, SoftReference<V>>(map);
+ copyOfMap.put(key, new SoftReference<V>(val));
+ map = copyOfMap;
+ return val;
}
- public void clear() {
- writersLock.lock();
- try {
- map.clear();
- } finally {
- writersLock.unlock();
- }
+ public synchronized void clear() {
+ /*
+ * Note that a copy on write pattern is used here so that the cache is
+ * cleared by assigning to a new empty cache.
+ */
+ map = new WeakHashMap<K, SoftReference<V>>();
}
}