All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.wink.common.internal.utils.SoftConcurrentMap Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 *     Licensed to the Apache Software Foundation (ASF) under one
 *     or more contributor license agreements.  See the NOTICE file
 *     distributed with this work for additional information
 *     regarding copyright ownership.  The ASF licenses this file
 *     to you 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.wink.common.internal.utils;

import java.lang.ref.SoftReference;
import java.util.ConcurrentModificationException;
import java.util.Map;
import java.util.WeakHashMap;

/**
 * Concurrent implementation of the SimpleMap interface. This implementation is
 * intend to be used by soft caches, therefore the keys are kept in WeakHashMap,
 * while the value is kept using the SoftReference.
 * 

* Pay attention that put value always returns the current value and not the * original value. It was done to allow the following code pattern: * *

 * SoftConcurrentMap<K, V> cache = new SoftConcurrentMap<K, V>();
 * V cached = cache.get(key);
 * return cached = !null ? cached : cache.put(createValue());
 * 
* * @param * @param */ public class SoftConcurrentMap implements SimpleMap { /* * Note that this volatile variable is important for publication purposes. */ private volatile Map> map; /** * Provides the map implementation. * * @param map */ public SoftConcurrentMap() { this.map = new WeakHashMap>(); } public V get(K key) { SoftReference softReference = map.get(key); return softReference != null ? softReference.get() : null; } /** * Associates the specified value with the specified key in this map. If the * map previously contained a mapping for this key, the old value is * replaced by the specified value. *

* Unlike the regular Map.put method, this method returns the current value * and not the previous value. *

* 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 synchronized V put(K key, V val) { /* * under the WeakHashMap(Map) constructor, java.util.AbstractMap.putAll is called, which uses * an iterator. Iterators, as we all know, are not thread-safe; they are susceptible * to ConcurrentModificationExceptions. Note that this method is already 'synchronized'. * However, that does not protect this.map from the silent garbage collector thread, which * may remove something at any time due to the internal values being "SoftReferences". * Instead of synchronizing on this.map, let's just catch ConcurrentModificationException * ignore it, and retry in the while loop. */ // non-null to avoid NPE when the timing of multi-threaded runs conspire against us WeakHashMap> copyOfMap = new WeakHashMap>(); boolean complete = false; while (!complete) { try { copyOfMap = new WeakHashMap>(map); complete = true; } catch (ConcurrentModificationException e) { // ignored } } copyOfMap.put(key, new SoftReference(val)); map = copyOfMap; return val; } 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>(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy