Java Code Examples for java.util.concurrent.ConcurrentMap#replace()
The following examples show how to use
java.util.concurrent.ConcurrentMap#replace() .
These examples are extracted from open source projects.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: jenkins-datadog-plugin File: ConcurrentMetricCounters.java License: MIT License | 6 votes |
public synchronized void increment(String name, String hostname, Map<String, Set<String>> tags) { ConcurrentMap<CounterMetric, Integer> counters = ConcurrentMetricCounters.get(); CounterMetric counterMetric = new CounterMetric(tags, name, hostname); Integer previousValue = counters.putIfAbsent(counterMetric, 1); if (previousValue != null){ boolean ok = counters.replace(counterMetric, previousValue, previousValue + 1); // NOTE: // This while loop below should never be called since we are using a lock when flushing and // incrementing counters. while(!ok) { logger.warning("Couldn't increment counter " + name + " with value " + (previousValue + 1) + " previousValue = " + previousValue); previousValue = counters.get(counterMetric); ok = counters.replace(counterMetric, previousValue, previousValue + 1); } } previousValue = previousValue == null ? 0 : previousValue; logger.fine("Counter " + name + " updated from previousValue " + previousValue + " to " + (previousValue + 1)); }
Example 2
Source Project: spotbugs File: Bug2898106a.java License: GNU Lesser General Public License v2.1 | 6 votes |
static Semaphore getLock(ConcurrentMap<String, Semaphore> locks2, String key) { Semaphore lock = locks2.get(key); if (lock == null) { Semaphore newLock = new Semaphore(1, true); locks2.get(null); locks2.put(null, null); locks2.remove(null); locks2.containsKey(null); locks2.containsValue(null); locks2.putIfAbsent(null, null); locks2.remove(null, null); locks2.replace(null, null); locks2.replace(null, null, null); lock = locks2.putIfAbsent(key, lock); // value, being null, will *always* throw NullPointerException if (lock == null) lock = newLock; } return lock; }
Example 3
Source Project: hbase File: SequenceIdAccounting.java License: Apache License 2.0 | 5 votes |
/** * Update the store sequence id, e.g., upon executing in-memory compaction */ void updateStore(byte[] encodedRegionName, byte[] familyName, Long sequenceId, boolean onlyIfGreater) { if (sequenceId == null) { return; } Long highest = this.highestSequenceIds.get(encodedRegionName); if (highest == null || sequenceId > highest) { this.highestSequenceIds.put(encodedRegionName, sequenceId); } ImmutableByteArray familyNameWrapper = ImmutableByteArray.wrap(familyName); synchronized (this.tieLock) { ConcurrentMap<ImmutableByteArray, Long> m = getOrCreateLowestSequenceIds(encodedRegionName); boolean replaced = false; while (!replaced) { Long oldSeqId = m.get(familyNameWrapper); if (oldSeqId == null) { m.put(familyNameWrapper, sequenceId); replaced = true; } else if (onlyIfGreater) { if (sequenceId > oldSeqId) { replaced = m.replace(familyNameWrapper, oldSeqId, sequenceId); } else { return; } } else { // replace even if sequence id is not greater than oldSeqId m.put(familyNameWrapper, sequenceId); return; } } } }
Example 4
Source Project: caffeine File: ConcurrentHashMapTest.java License: Apache License 2.0 | 5 votes |
/** * replace(x, null, y) throws NPE */ public void testReplaceValue2_NullPointerException() { ConcurrentMap c = map(); try { c.replace("whatever", null, "A"); shouldThrow(); } catch (NullPointerException success) {} }
Example 5
Source Project: ignite File: MarshallerContextImpl.java License: Apache License 2.0 | 5 votes |
/** * @param item Item. */ public void onMappingAccepted(final MarshallerMappingItem item) { ConcurrentMap<Integer, MappedName> cache = getCacheFor(item.platformId()); cache.replace(item.typeId(), new MappedName(item.className(), true)); closProc.runLocalSafe(new MappingStoreTask(fileStore, item.platformId(), item.typeId(), item.className())); }
Example 6
Source Project: caffeine File: CacheBuilderGwtTest.java License: Apache License 2.0 | 4 votes |
public void testMapMethods() { Cache<Integer, Integer> cache = CaffeinatedGuava.build(Caffeine.newBuilder()); ConcurrentMap<Integer, Integer> asMap = cache.asMap(); cache.put(10, 100); cache.put(2, 52); asMap.replace(2, 79); asMap.replace(3, 60); assertEquals(null, cache.getIfPresent(3)); assertEquals(null, asMap.get(3)); assertEquals(Integer.valueOf(79), cache.getIfPresent(2)); assertEquals(Integer.valueOf(79), asMap.get(2)); asMap.replace(10, 100, 50); asMap.replace(2, 52, 99); assertEquals(Integer.valueOf(50), cache.getIfPresent(10)); assertEquals(Integer.valueOf(50), asMap.get(10)); assertEquals(Integer.valueOf(79), cache.getIfPresent(2)); assertEquals(Integer.valueOf(79), asMap.get(2)); asMap.remove(10, 100); asMap.remove(2, 79); assertEquals(Integer.valueOf(50), cache.getIfPresent(10)); assertEquals(Integer.valueOf(50), asMap.get(10)); assertEquals(null, cache.getIfPresent(2)); assertEquals(null, asMap.get(2)); asMap.putIfAbsent(2, 20); asMap.putIfAbsent(10, 20); assertEquals(Integer.valueOf(20), cache.getIfPresent(2)); assertEquals(Integer.valueOf(20), asMap.get(2)); assertEquals(Integer.valueOf(50), cache.getIfPresent(10)); assertEquals(Integer.valueOf(50), asMap.get(10)); }
Example 7
Source Project: concurrentlinkedhashmap File: ConcurrentMapTest.java License: Apache License 2.0 | 4 votes |
@Test(dataProvider = "guardedMap", expectedExceptions = NullPointerException.class) public void replace_withNullValue(ConcurrentMap<Integer, Integer> map) { map.replace(1, null); }
Example 8
Source Project: dragonwell8_jdk File: WeakCache.java License: GNU General Public License v2.0 | 4 votes |
/** * Look-up the value through the cache. This always evaluates the * {@code subKeyFactory} function and optionally evaluates * {@code valueFactory} function if there is no entry in the cache for given * pair of (key, subKey) or the entry has already been cleared. * * @param key possibly null key * @param parameter parameter used together with key to create sub-key and * value (should not be null) * @return the cached value (never null) * @throws NullPointerException if {@code parameter} passed in or * {@code sub-key} calculated by * {@code subKeyFactory} or {@code value} * calculated by {@code valueFactory} is null. */ public V get(K key, P parameter) { Objects.requireNonNull(parameter); expungeStaleEntries(); Object cacheKey = CacheKey.valueOf(key, refQueue); // lazily install the 2nd level valuesMap for the particular cacheKey ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey); if (valuesMap == null) { ConcurrentMap<Object, Supplier<V>> oldValuesMap = map.putIfAbsent(cacheKey, valuesMap = new ConcurrentHashMap<>()); if (oldValuesMap != null) { valuesMap = oldValuesMap; } } // create subKey and retrieve the possible Supplier<V> stored by that // subKey from valuesMap Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter)); Supplier<V> supplier = valuesMap.get(subKey); Factory factory = null; while (true) { if (supplier != null) { // supplier might be a Factory or a CacheValue<V> instance V value = supplier.get(); if (value != null) { return value; } } // else no supplier in cache // or a supplier that returned null (could be a cleared CacheValue // or a Factory that wasn't successful in installing the CacheValue) // lazily construct a Factory if (factory == null) { factory = new Factory(key, parameter, subKey, valuesMap); } if (supplier == null) { supplier = valuesMap.putIfAbsent(subKey, factory); if (supplier == null) { // successfully installed Factory supplier = factory; } // else retry with winning supplier } else { if (valuesMap.replace(subKey, supplier, factory)) { // successfully replaced // cleared CacheEntry / unsuccessful Factory // with our Factory supplier = factory; } else { // retry with current supplier supplier = valuesMap.get(subKey); } } } }
Example 9
Source Project: concurrentlinkedhashmap File: ConcurrentMapTest.java License: Apache License 2.0 | 4 votes |
@Test(dataProvider = "guardedMap", expectedExceptions = NullPointerException.class) public void replaceConditionally_withNullOldValue(ConcurrentMap<Integer, Integer> map) { map.replace(1, null, 3); }
Example 10
Source Project: openjdk-jdk8u File: WeakCache.java License: GNU General Public License v2.0 | 4 votes |
/** * Look-up the value through the cache. This always evaluates the * {@code subKeyFactory} function and optionally evaluates * {@code valueFactory} function if there is no entry in the cache for given * pair of (key, subKey) or the entry has already been cleared. * * @param key possibly null key * @param parameter parameter used together with key to create sub-key and * value (should not be null) * @return the cached value (never null) * @throws NullPointerException if {@code parameter} passed in or * {@code sub-key} calculated by * {@code subKeyFactory} or {@code value} * calculated by {@code valueFactory} is null. */ public V get(K key, P parameter) { Objects.requireNonNull(parameter); expungeStaleEntries(); Object cacheKey = CacheKey.valueOf(key, refQueue); // lazily install the 2nd level valuesMap for the particular cacheKey ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey); if (valuesMap == null) { ConcurrentMap<Object, Supplier<V>> oldValuesMap = map.putIfAbsent(cacheKey, valuesMap = new ConcurrentHashMap<>()); if (oldValuesMap != null) { valuesMap = oldValuesMap; } } // create subKey and retrieve the possible Supplier<V> stored by that // subKey from valuesMap Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter)); Supplier<V> supplier = valuesMap.get(subKey); Factory factory = null; while (true) { if (supplier != null) { // supplier might be a Factory or a CacheValue<V> instance V value = supplier.get(); if (value != null) { return value; } } // else no supplier in cache // or a supplier that returned null (could be a cleared CacheValue // or a Factory that wasn't successful in installing the CacheValue) // lazily construct a Factory if (factory == null) { factory = new Factory(key, parameter, subKey, valuesMap); } if (supplier == null) { supplier = valuesMap.putIfAbsent(subKey, factory); if (supplier == null) { // successfully installed Factory supplier = factory; } // else retry with winning supplier } else { if (valuesMap.replace(subKey, supplier, factory)) { // successfully replaced // cleared CacheEntry / unsuccessful Factory // with our Factory supplier = factory; } else { // retry with current supplier supplier = valuesMap.get(subKey); } } } }
Example 11
Source Project: openjdk-jdk8u-backup File: WeakCache.java License: GNU General Public License v2.0 | 4 votes |
/** * Look-up the value through the cache. This always evaluates the * {@code subKeyFactory} function and optionally evaluates * {@code valueFactory} function if there is no entry in the cache for given * pair of (key, subKey) or the entry has already been cleared. * * @param key possibly null key * @param parameter parameter used together with key to create sub-key and * value (should not be null) * @return the cached value (never null) * @throws NullPointerException if {@code parameter} passed in or * {@code sub-key} calculated by * {@code subKeyFactory} or {@code value} * calculated by {@code valueFactory} is null. */ public V get(K key, P parameter) { Objects.requireNonNull(parameter); expungeStaleEntries(); Object cacheKey = CacheKey.valueOf(key, refQueue); // lazily install the 2nd level valuesMap for the particular cacheKey ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey); if (valuesMap == null) { ConcurrentMap<Object, Supplier<V>> oldValuesMap = map.putIfAbsent(cacheKey, valuesMap = new ConcurrentHashMap<>()); if (oldValuesMap != null) { valuesMap = oldValuesMap; } } // create subKey and retrieve the possible Supplier<V> stored by that // subKey from valuesMap Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter)); Supplier<V> supplier = valuesMap.get(subKey); Factory factory = null; while (true) { if (supplier != null) { // supplier might be a Factory or a CacheValue<V> instance V value = supplier.get(); if (value != null) { return value; } } // else no supplier in cache // or a supplier that returned null (could be a cleared CacheValue // or a Factory that wasn't successful in installing the CacheValue) // lazily construct a Factory if (factory == null) { factory = new Factory(key, parameter, subKey, valuesMap); } if (supplier == null) { supplier = valuesMap.putIfAbsent(subKey, factory); if (supplier == null) { // successfully installed Factory supplier = factory; } // else retry with winning supplier } else { if (valuesMap.replace(subKey, supplier, factory)) { // successfully replaced // cleared CacheEntry / unsuccessful Factory // with our Factory supplier = factory; } else { // retry with current supplier supplier = valuesMap.get(subKey); } } } }
Example 12
Source Project: jdk8u-jdk File: WeakCache.java License: GNU General Public License v2.0 | 4 votes |
/** * Look-up the value through the cache. This always evaluates the * {@code subKeyFactory} function and optionally evaluates * {@code valueFactory} function if there is no entry in the cache for given * pair of (key, subKey) or the entry has already been cleared. * * @param key possibly null key * @param parameter parameter used together with key to create sub-key and * value (should not be null) * @return the cached value (never null) * @throws NullPointerException if {@code parameter} passed in or * {@code sub-key} calculated by * {@code subKeyFactory} or {@code value} * calculated by {@code valueFactory} is null. */ public V get(K key, P parameter) { Objects.requireNonNull(parameter); expungeStaleEntries(); Object cacheKey = CacheKey.valueOf(key, refQueue); // lazily install the 2nd level valuesMap for the particular cacheKey ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey); if (valuesMap == null) { ConcurrentMap<Object, Supplier<V>> oldValuesMap = map.putIfAbsent(cacheKey, valuesMap = new ConcurrentHashMap<>()); if (oldValuesMap != null) { valuesMap = oldValuesMap; } } // create subKey and retrieve the possible Supplier<V> stored by that // subKey from valuesMap Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter)); Supplier<V> supplier = valuesMap.get(subKey); Factory factory = null; while (true) { if (supplier != null) { // supplier might be a Factory or a CacheValue<V> instance V value = supplier.get(); if (value != null) { return value; } } // else no supplier in cache // or a supplier that returned null (could be a cleared CacheValue // or a Factory that wasn't successful in installing the CacheValue) // lazily construct a Factory if (factory == null) { factory = new Factory(key, parameter, subKey, valuesMap); } if (supplier == null) { supplier = valuesMap.putIfAbsent(subKey, factory); if (supplier == null) { // successfully installed Factory supplier = factory; } // else retry with winning supplier } else { if (valuesMap.replace(subKey, supplier, factory)) { // successfully replaced // cleared CacheEntry / unsuccessful Factory // with our Factory supplier = factory; } else { // retry with current supplier supplier = valuesMap.get(subKey); } } } }
Example 13
Source Project: Java8CN File: WeakCache.java License: Apache License 2.0 | 4 votes |
/** * Look-up the value through the cache. This always evaluates the * {@code subKeyFactory} function and optionally evaluates * {@code valueFactory} function if there is no entry in the cache for given * pair of (key, subKey) or the entry has already been cleared. * * @param key possibly null key * @param parameter parameter used together with key to create sub-key and * value (should not be null) * @return the cached value (never null) * @throws NullPointerException if {@code parameter} passed in or * {@code sub-key} calculated by * {@code subKeyFactory} or {@code value} * calculated by {@code valueFactory} is null. */ public V get(K key, P parameter) { Objects.requireNonNull(parameter); expungeStaleEntries(); Object cacheKey = CacheKey.valueOf(key, refQueue); // lazily install the 2nd level valuesMap for the particular cacheKey ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey); if (valuesMap == null) { ConcurrentMap<Object, Supplier<V>> oldValuesMap = map.putIfAbsent(cacheKey, valuesMap = new ConcurrentHashMap<>()); if (oldValuesMap != null) { valuesMap = oldValuesMap; } } // create subKey and retrieve the possible Supplier<V> stored by that // subKey from valuesMap Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter)); Supplier<V> supplier = valuesMap.get(subKey); Factory factory = null; while (true) { if (supplier != null) { // supplier might be a Factory or a CacheValue<V> instance V value = supplier.get(); if (value != null) { return value; } } // else no supplier in cache // or a supplier that returned null (could be a cleared CacheValue // or a Factory that wasn't successful in installing the CacheValue) // lazily construct a Factory if (factory == null) { factory = new Factory(key, parameter, subKey, valuesMap); } if (supplier == null) { supplier = valuesMap.putIfAbsent(subKey, factory); if (supplier == null) { // successfully installed Factory supplier = factory; } // else retry with winning supplier } else { if (valuesMap.replace(subKey, supplier, factory)) { // successfully replaced // cleared CacheEntry / unsuccessful Factory // with our Factory supplier = factory; } else { // retry with current supplier supplier = valuesMap.get(subKey); } } } }
Example 14
Source Project: concurrentlinkedhashmap File: ConcurrentMapTest.java License: Apache License 2.0 | 4 votes |
@Test(dataProvider = "guardedMap", expectedExceptions = NullPointerException.class) public void replaceConditionally_withNullKeyAndValues(ConcurrentMap<Integer, Integer> map) { map.replace(null, null, null); }
Example 15
Source Project: openjdk-8-source File: WeakCache.java License: GNU General Public License v2.0 | 4 votes |
/** * Look-up the value through the cache. This always evaluates the * {@code subKeyFactory} function and optionally evaluates * {@code valueFactory} function if there is no entry in the cache for given * pair of (key, subKey) or the entry has already been cleared. * * @param key possibly null key * @param parameter parameter used together with key to create sub-key and * value (should not be null) * @return the cached value (never null) * @throws NullPointerException if {@code parameter} passed in or * {@code sub-key} calculated by * {@code subKeyFactory} or {@code value} * calculated by {@code valueFactory} is null. */ public V get(K key, P parameter) { Objects.requireNonNull(parameter); expungeStaleEntries(); Object cacheKey = CacheKey.valueOf(key, refQueue); // lazily install the 2nd level valuesMap for the particular cacheKey ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey); if (valuesMap == null) { ConcurrentMap<Object, Supplier<V>> oldValuesMap = map.putIfAbsent(cacheKey, valuesMap = new ConcurrentHashMap<>()); if (oldValuesMap != null) { valuesMap = oldValuesMap; } } // create subKey and retrieve the possible Supplier<V> stored by that // subKey from valuesMap Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter)); Supplier<V> supplier = valuesMap.get(subKey); Factory factory = null; while (true) { if (supplier != null) { // supplier might be a Factory or a CacheValue<V> instance V value = supplier.get(); if (value != null) { return value; } } // else no supplier in cache // or a supplier that returned null (could be a cleared CacheValue // or a Factory that wasn't successful in installing the CacheValue) // lazily construct a Factory if (factory == null) { factory = new Factory(key, parameter, subKey, valuesMap); } if (supplier == null) { supplier = valuesMap.putIfAbsent(subKey, factory); if (supplier == null) { // successfully installed Factory supplier = factory; } // else retry with winning supplier } else { if (valuesMap.replace(subKey, supplier, factory)) { // successfully replaced // cleared CacheEntry / unsuccessful Factory // with our Factory supplier = factory; } else { // retry with current supplier supplier = valuesMap.get(subKey); } } } }
Example 16
Source Project: jdk8u_jdk File: WeakCache.java License: GNU General Public License v2.0 | 4 votes |
/** * Look-up the value through the cache. This always evaluates the * {@code subKeyFactory} function and optionally evaluates * {@code valueFactory} function if there is no entry in the cache for given * pair of (key, subKey) or the entry has already been cleared. * * @param key possibly null key * @param parameter parameter used together with key to create sub-key and * value (should not be null) * @return the cached value (never null) * @throws NullPointerException if {@code parameter} passed in or * {@code sub-key} calculated by * {@code subKeyFactory} or {@code value} * calculated by {@code valueFactory} is null. */ public V get(K key, P parameter) { Objects.requireNonNull(parameter); expungeStaleEntries(); Object cacheKey = CacheKey.valueOf(key, refQueue); // lazily install the 2nd level valuesMap for the particular cacheKey ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey); if (valuesMap == null) { ConcurrentMap<Object, Supplier<V>> oldValuesMap = map.putIfAbsent(cacheKey, valuesMap = new ConcurrentHashMap<>()); if (oldValuesMap != null) { valuesMap = oldValuesMap; } } // create subKey and retrieve the possible Supplier<V> stored by that // subKey from valuesMap Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter)); Supplier<V> supplier = valuesMap.get(subKey); Factory factory = null; while (true) { if (supplier != null) { // supplier might be a Factory or a CacheValue<V> instance V value = supplier.get(); if (value != null) { return value; } } // else no supplier in cache // or a supplier that returned null (could be a cleared CacheValue // or a Factory that wasn't successful in installing the CacheValue) // lazily construct a Factory if (factory == null) { factory = new Factory(key, parameter, subKey, valuesMap); } if (supplier == null) { supplier = valuesMap.putIfAbsent(subKey, factory); if (supplier == null) { // successfully installed Factory supplier = factory; } // else retry with winning supplier } else { if (valuesMap.replace(subKey, supplier, factory)) { // successfully replaced // cleared CacheEntry / unsuccessful Factory // with our Factory supplier = factory; } else { // retry with current supplier supplier = valuesMap.get(subKey); } } } }
Example 17
Source Project: concurrentlinkedhashmap File: ConcurrentMapTest.java License: Apache License 2.0 | 4 votes |
@Test(dataProvider = "guardedMap", expectedExceptions = NullPointerException.class) public void replaceConditionally_withNullNewValue(ConcurrentMap<Integer, Integer> map) { map.replace(1, 2, null); }
Example 18
Source Project: concurrentlinkedhashmap File: ConcurrentMapTest.java License: Apache License 2.0 | 4 votes |
@Test(dataProvider = "guardedMap", expectedExceptions = NullPointerException.class) public void replaceConditionally_withNullKeyAndNewValue(ConcurrentMap<Integer, Integer> map) { map.replace(null, 2, null); }
Example 19
Source Project: streamsupport File: ConcurrentMaps.java License: GNU General Public License v2.0 | 4 votes |
/** * Attempts to compute a mapping for the specified key and its current * mapped value (or {@code null} if there is no current mapping). For * example, to either create or append a {@code String} msg to a value * mapping: * * <pre> {@code * map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))}</pre> * (Method {@link #merge merge()} is often simpler to use for such purposes.) * * <p>If the remapping function returns {@code null}, the mapping is removed * (or remains absent if initially absent). If the remapping function itself * throws an (unchecked) exception, the exception is rethrown, and the current * mapping is left unchanged. * * <p>The remapping function itself should not modify the passed map during * computation. * * <p><b>Implementation Requirements:</b><br> * The default implementation is equivalent to performing the following * steps for the {@code map}: * * <pre> {@code * for (;;) { * V oldValue = map.get(key); * V newValue = remappingFunction.apply(key, oldValue); * if (newValue != null) { * if ((oldValue != null) * ? map.replace(key, oldValue, newValue) * : map.putIfAbsent(key, newValue) == null) * return newValue; * } else if (oldValue == null || map.remove(key, oldValue)) { * return null; * } * }}</pre> * When multiple threads attempt updates, map operations and the * remapping function may be called multiple times. * * <p>This implementation assumes that the ConcurrentMap cannot contain null * values and {@code get()} returning null unambiguously means the key is * absent. Implementations which support null values <strong>must</strong> * override this default implementation. * * @param <K> the type of keys maintained by the passed map * @param <V> the type of mapped values in the passed map * @param map the {@code ConcurrentMap} on which to execute the {@code compute} * operation. * @param key key with which the specified value is to be associated * @param remappingFunction the remapping function to compute a value * @return the new value associated with the specified key, or null if none * @throws NullPointerException if the specified key is null and * the map does not support null keys, or the * remappingFunction is null * @throws UnsupportedOperationException if the {@code put} operation * is not supported by the map (optional) * @throws ClassCastException if the class of the specified key or value * prevents it from being stored in the map (optional) * @throws IllegalArgumentException if some property of the specified key * or value prevents it from being stored in this map (optional) * @since 1.8 */ public static <K, V> V compute(ConcurrentMap<K, V> map, K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { Objects.requireNonNull(map); retry: for (;;) { V oldValue = map.get(key); // if putIfAbsent fails, opportunistically use its return value haveOldValue: for (;;) { V newValue = remappingFunction.apply(key, oldValue); if (newValue != null) { if (oldValue != null) { if (map.replace(key, oldValue, newValue)) return newValue; } else if ((oldValue = map.putIfAbsent(key, newValue)) == null) return newValue; else continue haveOldValue; } else if (oldValue == null || map.remove(key, oldValue)) { return null; } continue retry; } } }
Example 20
Source Project: jdk8u-jdk File: WeakCache.java License: GNU General Public License v2.0 | 4 votes |
/** * Look-up the value through the cache. This always evaluates the * {@code subKeyFactory} function and optionally evaluates * {@code valueFactory} function if there is no entry in the cache for given * pair of (key, subKey) or the entry has already been cleared. * * @param key possibly null key * @param parameter parameter used together with key to create sub-key and * value (should not be null) * @return the cached value (never null) * @throws NullPointerException if {@code parameter} passed in or * {@code sub-key} calculated by * {@code subKeyFactory} or {@code value} * calculated by {@code valueFactory} is null. */ public V get(K key, P parameter) { Objects.requireNonNull(parameter); expungeStaleEntries(); Object cacheKey = CacheKey.valueOf(key, refQueue); // lazily install the 2nd level valuesMap for the particular cacheKey ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey); if (valuesMap == null) { ConcurrentMap<Object, Supplier<V>> oldValuesMap = map.putIfAbsent(cacheKey, valuesMap = new ConcurrentHashMap<>()); if (oldValuesMap != null) { valuesMap = oldValuesMap; } } // create subKey and retrieve the possible Supplier<V> stored by that // subKey from valuesMap Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter)); Supplier<V> supplier = valuesMap.get(subKey); Factory factory = null; while (true) { if (supplier != null) { // supplier might be a Factory or a CacheValue<V> instance V value = supplier.get(); if (value != null) { return value; } } // else no supplier in cache // or a supplier that returned null (could be a cleared CacheValue // or a Factory that wasn't successful in installing the CacheValue) // lazily construct a Factory if (factory == null) { factory = new Factory(key, parameter, subKey, valuesMap); } if (supplier == null) { supplier = valuesMap.putIfAbsent(subKey, factory); if (supplier == null) { // successfully installed Factory supplier = factory; } // else retry with winning supplier } else { if (valuesMap.replace(subKey, supplier, factory)) { // successfully replaced // cleared CacheEntry / unsuccessful Factory // with our Factory supplier = factory; } else { // retry with current supplier supplier = valuesMap.get(subKey); } } } }