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

org.apache.commons.collections4.map.ConcurrentReferenceHashMap Maven / Gradle / Ivy

Go to download

The Apache Commons Collections package contains types that extend and augment the Java Collections Framework.

There is a newer version: 4.5.0-M3
Show 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.
 */

/*
 * Copyright (c) 2008-2020, Hazelcast, Inc. All Rights Reserved.
 */

package org.apache.commons.collections4.map;

/*
 * Written by Doug Lea with assistance from members of JCP JSR-166
 * Expert Group and released to the public domain, as explained at
 * http://creativecommons.org/licenses/publicdomain
 */

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Arrays;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * An advanced hash map supporting configurable garbage collection semantics of keys and values, optional referential-equality, full concurrency of retrievals,
 * and adjustable expected concurrency for updates.
 * 

* This map is designed around specific advanced use-cases. If there is any doubt whether this map is for you, you most likely should be using * {@link java.util.concurrent.ConcurrentHashMap} instead. *

*

* This map supports strong, weak, and soft keys and values. By default, keys are weak, and values are strong. Such a configuration offers similar behavior to * {@link java.util.WeakHashMap}, entries of this map are periodically removed once their corresponding keys are no longer referenced outside of this map. In * other words, this map will not prevent a key from being discarded by the garbage collector. Once a key has been discarded by the collector, the corresponding * entry is no longer visible to this map; however, the entry may occupy space until a future map operation decides to reclaim it. For this reason, summary * functions such as {@code size} and {@code isEmpty} might return a value greater than the observed number of entries. In order to support a high level of * concurrency, stale entries are only reclaimed during blocking (usually mutating) operations. *

*

* Enabling soft keys allows entries in this map to remain until their space is absolutely needed by the garbage collector. This is unlike weak keys which can * be reclaimed as soon as they are no longer referenced by a normal strong reference. The primary use case for soft keys is a cache, which ideally occupies * memory that is not in use for as long as possible. *

*

* By default, values are held using a normal strong reference. This provides the commonly desired guarantee that a value will always have at least the same * life-span as its key. For this reason, care should be taken to ensure that a value never refers, either directly or indirectly, to its key, thereby * preventing reclamation. If this is unavoidable, then it is recommended to use the same reference type in use for the key. However, it should be noted that * non-strong values may disappear before their corresponding key. *

*

* While this map does allow the use of both strong keys and values, it is recommended you use {@link java.util.concurrent.ConcurrentHashMap} for such a * configuration, since it is optimized for that case. *

*

* Just like {@link java.util.concurrent.ConcurrentHashMap}, this class obeys the same functional specification as {@link Hashtable}, and includes versions of * methods corresponding to each method of {@code Hashtable}. However, even though all operations are thread-safe, retrieval operations do not entail * locking, and there is not any support for locking the entire map in a way that prevents all access. This class is fully interoperable with * {@code Hashtable} in programs that rely on its thread safety but not on its synchronization details. *

*

* Retrieval operations (including {@code get}) generally do not block, so they may overlap with update operations (including {@code put} and {@code remove}). * Retrievals reflect the results of the most recently completed update operations holding upon their onset. For aggregate operations such as * {@code putAll} and {@code clear}, concurrent retrievals may reflect insertion or removal of only some entries. Similarly, Iterators and Enumerations return * elements reflecting the state of the hash map at some point at or since the creation of the iterator/enumeration. They do not throw * {@link ConcurrentModificationException}. However, iterators are designed to be used by only one thread at a time. *

*

* The allowed concurrency among update operations is guided by the optional {@code concurrencyLevel} constructor argument (default * {@value #DEFAULT_CONCURRENCY_LEVEL}), which is used as a hint for internal sizing. The map is internally partitioned to try to permit the indicated number of * concurrent updates without contention. Because placement in hash tables is essentially random, the actual concurrency will vary. Ideally, you should choose a * value to accommodate as many threads as will ever concurrently modify the map. Using a significantly higher value than you need can waste space and time, and * a significantly lower value can lead to thread contention. But overestimates and underestimates within an order of magnitude do not usually have much * noticeable impact. A value of one is appropriate when it is known that only one thread will modify and all others will only read. Also, resizing this or any * other kind of hash map is a relatively slow operation, so, when possible, it is a good idea that you provide estimates of expected map sizes in constructors. *

*

* This class and its views and iterators implement all of the optional methods of the {@link Map} and {@link Iterator} interfaces. *

*

* Like {@link Hashtable} but unlike {@link HashMap}, this class does not allow {@code null} to be used as a key or value. *

*

* Provenance: Copied and edited from Apache Groovy git master at commit 77dc80a7512ceb2168b1bc866c3d0c69b002fe11; via Doug Lea, Jason T. Greene, with * assistance from members of JCP JSR-166, and Hazelcast. *

* * @param the type of keys maintained by this map. * @param the type of mapped values. */ public class ConcurrentReferenceHashMap extends AbstractMap implements ConcurrentMap { /** * Builds new ConcurrentReferenceHashMap instances. *

* By default, keys are weak, and values are strong. *

*

* The default values are: *

*
    *
  • concurrency level: {@value #DEFAULT_CONCURRENCY_LEVEL}
  • *
  • initial capacity: {@value #DEFAULT_INITIAL_CAPACITY}
  • *
  • key reference type: {@link ReferenceType#WEAK}
  • *
  • load factor: {@value #DEFAULT_LOAD_FACTOR}
  • *
  • options: {@code null}
  • *
  • source map: {@code null}
  • *
  • value reference type: {@link ReferenceType#STRONG}
  • *
* * @param the type of keys. * @param the type of values. */ public static class Builder implements Supplier> { private static final Map DEFAULT_SOURCE_MAP = null; private int initialCapacity = DEFAULT_INITIAL_CAPACITY; private float loadFactor = DEFAULT_LOAD_FACTOR; private int concurrencyLevel = DEFAULT_CONCURRENCY_LEVEL; private ReferenceType keyReferenceType = DEFAULT_KEY_TYPE; private ReferenceType valueReferenceType = DEFAULT_VALUE_TYPE; private EnumSet