Package org.springframework.util

# Class ConcurrentReferenceHashMap<K,V>

java.lang.Object
java.util.AbstractMap<K,V>
org.springframework.util.ConcurrentReferenceHashMap<K,V>

Type Parameters:
  `K` - the key type
  `V` - the value type

All Implemented Interfaces:
  `ConcurrentMap<K,V>`, `Map<K,V>`

public class ConcurrentReferenceHashMap<K,V> extends AbstractMap<K,V> implements ConcurrentMap<K,V>
A `ConcurrentHashMap` variant that uses `soft` or weak references for both `keys` and `values`.

This class can be used as an alternative to `Collections.synchronizedMap(new WeakHashMap<K, Reference<V>>())` in order to support better performance when accessed concurrently. This implementation follows the same design constraints as `ConcurrentHashMap` with the exception that `null` values and `null` keys are supported.

NOTE: The use of references means that there is no guarantee that items placed into the map will be subsequently available. The garbage collector may discard references at any time, so it may appear that an unknown thread is silently removing entries.

If not explicitly specified, this implementation will use soft entry references.

Since:
  3.2
Author:
  Phillip Webb, Juergen Hoeller, Brian Clozel

## Nested Class Summary

Nested Classes
Modifier and Type
Class
Description
`protected static final class`
`ConcurrentReferenceHashMap.Entry<K,V>`
A single map entry.
`protected static interface`
`ConcurrentReferenceHashMap.Reference<K,V>`
A reference to an `ConcurrentReferenceHashMap.Entry` contained in the map.
`protected class`
`ConcurrentReferenceHashMap.ReferenceManager`
Strategy class used to manage `References`.
`static enum`
`ConcurrentReferenceHashMap.ReferenceType`
Various reference types supported by this map.
`protected static enum`
`ConcurrentReferenceHashMap.Restructure`
The types of restructuring that can be performed.
`protected final class`
`ConcurrentReferenceHashMap.Segment`
A single segment used to divide the map to allow better concurrent performance.

## Nested classes/interfaces inherited from class java.util.AbstractMap

`AbstractMap.SimpleEntry<K extends Object,V extends Object>, AbstractMap.SimpleImmutableEntry<K extends Object,V extends Object>`

## Constructor Summary

Constructors
Constructor
Description
`ConcurrentReferenceHashMap()`
Create a new `ConcurrentReferenceHashMap` instance.
`ConcurrentReferenceHashMap(int initialCapacity)`
Create a new `ConcurrentReferenceHashMap` instance.
`ConcurrentReferenceHashMap(int initialCapacity, float loadFactor)`
Create a new `ConcurrentReferenceHashMap` instance.
`ConcurrentReferenceHashMap(int initialCapacity, float loadFactor, int concurrencyLevel)`
Create a new `ConcurrentReferenceHashMap` instance.
`ConcurrentReferenceHashMap(int initialCapacity, float loadFactor, int concurrencyLevel, ConcurrentReferenceHashMap.ReferenceType referenceType)`
Create a new `ConcurrentReferenceHashMap` instance.
`ConcurrentReferenceHashMap(int initialCapacity, int concurrencyLevel)`
Create a new `ConcurrentReferenceHashMap` instance.
`ConcurrentReferenceHashMap(int initialCapacity, ConcurrentReferenceHashMap.ReferenceType referenceType)`
Create a new `ConcurrentReferenceHashMap` instance.

## Method Summary

Modifier and Type
Method
Description
`protected static int`
`calculateShift(int minimumValue, int maximumValue)`
Calculate a shift value that can be used to create a power-of-two value between the specified maximum and minimum values.
`void`
`clear()`
`V`
`compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)`
`V`
`computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)`
`V`
`computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)`
`boolean`
`containsKey(Object key)`
`protected ConcurrentReferenceHashMap<K,V>.ReferenceManager`
`createReferenceManager()`
Factory method that returns the `ConcurrentReferenceHashMap<K,V>.ReferenceManager`.
`Set<Map.Entry<K,V>>`
`entrySet()`
`V`
`get(Object key)`
`protected int`
`getHash(Object o)`
Get the hash for a given object, apply an additional hash function to reduce collisions.
`protected final float`
`getLoadFactor()`
`V`
`getOrDefault(Object key, V defaultValue)`
`protected final ConcurrentReferenceHashMap.Reference<K,V>`
`getReference(Object key, ConcurrentReferenceHashMap.Restructure restructure)`
Return a `ConcurrentReferenceHashMap.Reference` to the `ConcurrentReferenceHashMap.Entry` for the specified `key`, or `null` if not found.
`protected final ConcurrentReferenceHashMap<K,V>.Segment`
`getSegment(int index)`
`protected final int`
`getSegmentsSize()`
`boolean`
`isEmpty()`
`Set<K>`
`keySet()`
`V`
`merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)`
`void`
`purgeUnreferencedEntries()`
Remove any entries that have been garbage-collected and are no longer referenced.
`V`
`put(K key, V value)`
`V`
`putIfAbsent(K key, V value)`
`V`
`remove(Object key)`
`boolean`
`remove(Object key, Object value)`
`V`
`replace(K key, V value)`
`boolean`
`replace(K key, V oldValue, V newValue)`
`int`
`size()`
`Collection<V>`
`values()`

### Methods inherited from class java.util.AbstractMap

`clone, containsValue, equals, hashCode, putAll, toString`

### Methods inherited from class java.lang.Object

`finalize, getClass, notify, notifyAll, wait, wait, wait`

### Methods inherited from interface java.util.concurrent.ConcurrentMap

`forEach, replaceAll`

### Methods inherited from interface java.util.Map

`containsValue, equals, hashCode, putAll`

## Constructor Details

### ConcurrentReferenceHashMap

public ConcurrentReferenceHashMap()
Create a new `ConcurrentReferenceHashMap` instance.

### ConcurrentReferenceHashMap

public ConcurrentReferenceHashMap(int initialCapacity)
Create a new `ConcurrentReferenceHashMap` instance.

Parameters:
  `initialCapacity` - the initial capacity of the map

### ConcurrentReferenceHashMap

public ConcurrentReferenceHashMap(int initialCapacity, float loadFactor)
Create a new `ConcurrentReferenceHashMap` instance.

Parameters:
  `initialCapacity` - the initial capacity of the map
  `loadFactor` - the load factor. When the average number of references per table exceeds this value resize will be attempted

### ConcurrentReferenceHashMap

public ConcurrentReferenceHashMap(int initialCapacity, int concurrencyLevel)
Create a new `ConcurrentReferenceHashMap` instance.

Parameters:
  `initialCapacity` - the initial capacity of the map
  `concurrencyLevel` - the expected number of threads that will concurrently write to the map

### ConcurrentReferenceHashMap

public ConcurrentReferenceHashMap(int initialCapacity, ConcurrentReferenceHashMap.ReferenceType referenceType)
Create a new `ConcurrentReferenceHashMap` instance.

Parameters:
  `initialCapacity` - the initial capacity of the map
  `referenceType` - the reference type used for entries (soft or weak)

### ConcurrentReferenceHashMap

public ConcurrentReferenceHashMap(int initialCapacity, float loadFactor, int concurrencyLevel)
Create a new `ConcurrentReferenceHashMap` instance.

Parameters:
  `initialCapacity` - the initial capacity of the map
  `loadFactor` - the load factor. When the average number of references per table exceeds this value, resize will be attempted.
  `concurrencyLevel` - the expected number of threads that will concurrently write to the map

### ConcurrentReferenceHashMap

public ConcurrentReferenceHashMap(int initialCapacity, float loadFactor, int concurrencyLevel, ConcurrentReferenceHashMap.ReferenceType referenceType)
Create a new `ConcurrentReferenceHashMap` instance.

Parameters:
  `initialCapacity` - the initial capacity of the map
  `loadFactor` - the load factor. When the average number of references per table exceeds this value, resize will be attempted.
  `concurrencyLevel` - the expected number of threads that will concurrently write to the map
  `referenceType` - the reference type used for entries (soft or weak)

## Method Details

### getLoadFactor

protected final float getLoadFactor()

### getSegmentsSize

protected final int getSegmentsSize()

### getSegment

protected final ConcurrentReferenceHashMap<K,V>.Segment getSegment(int index)

### createReferenceManager

protected ConcurrentReferenceHashMap<K,V>.ReferenceManager createReferenceManager()
Factory method that returns the `ConcurrentReferenceHashMap<K,V>.ReferenceManager`. This method will be called once for each `ConcurrentReferenceHashMap<K,V>.Segment`.

Returns:
  a new reference manager

### getHash

protected int getHash(@Nullable Object o)
Get the hash for a given object, apply an additional hash function to reduce collisions. This implementation uses the same Wang/Jenkins algorithm as `ConcurrentHashMap`. Subclasses can override to provide alternative hashing.

Parameters:
  `o` - the object to hash (may be null)
Returns:
  the resulting hash code

### get

@Nullable public V get(@Nullable Object key)

Specified by:
  `get` in interface `Map<K,V>`
Overrides:
  `get` in class `AbstractMap<K,V>`

### getOrDefault

@Nullable public V getOrDefault(@Nullable Object key, @Nullable V defaultValue)

Specified by:
  `getOrDefault` in interface `ConcurrentMap<K,V>`
Specified by:
  `getOrDefault` in interface `Map<K,V>`

### containsKey

public boolean containsKey(@Nullable Object key)

Specified by:
  `containsKey` in interface `Map<K,V>`
Overrides:
  `containsKey` in class `AbstractMap<K,V>`

### getReference

@Nullable protected final ConcurrentReferenceHashMap.Reference<K,V> getReference(@Nullable Object key, ConcurrentReferenceHashMap.Restructure restructure)
Return a `ConcurrentReferenceHashMap.Reference` to the `ConcurrentReferenceHashMap.Entry` for the specified `key`, or `null` if not found.

Parameters:
  `key` - the key (can be `null`)
  `restructure` - types of restructure allowed during this call
Returns:
  the reference, or `null` if not found

### put

@Nullable public V put(@Nullable K key, @Nullable V value)

Specified by:
  `put` in interface `Map<K,V>`
Overrides:
  `put` in class `AbstractMap<K,V>`

### putIfAbsent

@Nullable public V putIfAbsent(@Nullable K key, @Nullable V value)

Specified by:
  `putIfAbsent` in interface `ConcurrentMap<K,V>`
Specified by:
  `putIfAbsent` in interface `Map<K,V>`

### remove

@Nullable public V remove(@Nullable Object key)

Specified by:
  `remove` in interface `Map<K,V>`
Overrides:
  `remove` in class `AbstractMap<K,V>`

### remove

public boolean remove(@Nullable Object key, @Nullable Object value)

Specified by:
  `remove` in interface `ConcurrentMap<K,V>`
Specified by:
  `remove` in interface `Map<K,V>`

### replace

public boolean replace(@Nullable K key, @Nullable V oldValue, @Nullable V newValue)

Specified by:
  `replace` in interface `ConcurrentMap<K,V>`
Specified by:
  `replace` in interface `Map<K,V>`

### replace

@Nullable public V replace(@Nullable K key, @Nullable V value)

Specified by:
  `replace` in interface `ConcurrentMap<K,V>`
Specified by:
  `replace` in interface `Map<K,V>`

### computeIfAbsent

@Nullable public V computeIfAbsent(@Nullable K key, Function<? super K,? extends V> mappingFunction)

Specified by:
  `computeIfAbsent` in interface `ConcurrentMap<K,V>`
Specified by:
  `computeIfAbsent` in interface `Map<K,V>`

### computeIfPresent

@Nullable public V computeIfPresent(@Nullable K key, BiFunction<? super K,? super V,? extends V> remappingFunction)

Specified by:
  `computeIfPresent` in interface `ConcurrentMap<K,V>`
Specified by:
  `computeIfPresent` in interface `Map<K,V>`

### compute

@Nullable public V compute(@Nullable K key, BiFunction<? super K,? super V,? extends V> remappingFunction)

Specified by:
  `compute` in interface `ConcurrentMap<K,V>`
Specified by:
  `compute` in interface `Map<K,V>`

### merge

@Nullable public V merge(@Nullable K key, @Nullable V value, BiFunction<? super V,? super V,? extends V> remappingFunction)

Specified by:
  `merge` in interface `ConcurrentMap<K,V>`
Specified by:
  `merge` in interface `Map<K,V>`

### clear

public void clear()

Specified by:
  `clear` in interface `Map<K,V>`
Overrides:
  `clear` in class `AbstractMap<K,V>`

### purgeUnreferencedEntries

public void purgeUnreferencedEntries()
Remove any entries that have been garbage-collected and are no longer referenced. Note that this call implies segment locking and can lead to thread contention.

Under normal circumstances, garbage-collected entries are automatically purged as items are added or removed from the Map. This method can be used to force a purge which is useful when the Map is read frequently but hardly ever updated anymore.

Note that it may be preferable to simply `clear` the entire cache at certain points of the lifecycle, not just dropping unreferenced entries but even the entire cache content: assuming that most entries in the cache won't be needed anymore after certain processing phases, therefore rather rebuilding the cache going forward.

Since:
  4.1.1
See Also:
  - `clear()`

### size

public int size()

Specified by:
  `size` in interface `Map<K,V>`
Overrides:
  `size` in class `AbstractMap<K,V>`

### isEmpty

public boolean isEmpty()

Specified by:
  `isEmpty` in interface `Map<K,V>`
Overrides:
  `isEmpty` in class `AbstractMap<K,V>`

### entrySet

public Set<Map.Entry<K,V>> entrySet()

Specified by:
  `entrySet` in interface `Map<K,V>`
Specified by:
  `entrySet` in class `AbstractMap<K,V>`

### keySet

public Set<K> keySet()

Specified by:
  `keySet` in interface `Map<K,V>`
Overrides:
  `keySet` in class `AbstractMap<K,V>`

### values

public Collection<V> values()

Specified by:
  `values` in interface `Map<K,V>`
Overrides:
  `values` in class `AbstractMap<K,V>`

### calculateShift

protected static int calculateShift(int minimumValue, int maximumValue)
Calculate a shift value that can be used to create a power-of-two value between the specified maximum and minimum values.

Parameters:
  `minimumValue` - the minimum value
  `maximumValue` - the maximum value
Returns:
  the calculated shift (use `1 << shift` to obtain a value)