2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation. Oracle designates this
7 * particular file as subject to the "Classpath" exception as provided
8 * by Oracle in the LICENSE file that accompanied this code.
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
26 * This file is available under and governed by the GNU General Public
27 * License version 2 only, as published by the Free Software Foundation.
28 * However, the following notice accompanied the original version of this
31 * Written by Doug Lea with assistance from members of JCP JSR-166
32 * Expert Group and released to the public domain, as explained at
33 * http://creativecommons.org/publicdomain/zero/1.0/
35 package java.util.concurrent;
38 import java.io.Serializable;
39 import java.io.IOException;
40 import java.io.ObjectInputStream;
41 import java.io.ObjectOutputStream;
44 * A hash table supporting full concurrency of retrievals and adjustable
45 * expected concurrency for updates. This class obeys the same functional
46 * specification as {@link java.util.Hashtable}, and includes versions of
47 * methods corresponding to each method of
48 * <tt>Hashtable</tt>. However, even though all operations are thread-safe,
49 * retrieval operations do <em>not</em> entail locking, and there is
50 * <em>not</em> any support for locking the entire table in a way that prevents
51 * all access. This class is fully interoperable with <tt>Hashtable</tt> in
52 * programs that rely on its thread safety but not on its synchronization
56 * Retrieval operations (including <tt>get</tt>) generally do not block, so may
57 * overlap with update operations (including
58 * <tt>put</tt> and <tt>remove</tt>). Retrievals reflect the results of the most
59 * recently <em>completed</em> update operations holding upon their onset. For
60 * aggregate operations such as <tt>putAll</tt>
61 * and <tt>clear</tt>, concurrent retrievals may reflect insertion or removal of
62 * only some entries. Similarly, Iterators and Enumerations return elements
63 * reflecting the state of the hash table at some point at or since the creation
64 * of the iterator/enumeration. They do <em>not</em> throw
65 * {@link ConcurrentModificationException}. However, iterators are designed to
66 * be used by only one thread at a time.
69 * The allowed concurrency among update operations is guided by the optional
70 * <tt>concurrencyLevel</tt> constructor argument (default <tt>16</tt>), which
71 * is used as a hint for internal sizing. The table is internally partitioned to
72 * try to permit the indicated number of concurrent updates without contention.
73 * Because placement in hash tables is essentially random, the actual
74 * concurrency will vary. Ideally, you should choose a value to accommodate as
75 * many threads as will ever concurrently modify the table. Using a
76 * significantly higher value than you need can waste space and time, and a
77 * significantly lower value can lead to thread contention. But overestimates
78 * and underestimates within an order of magnitude do not usually have much
79 * noticeable impact. A value of one is appropriate when it is known that only
80 * one thread will modify and all others will only read. Also, resizing this or
81 * any other kind of hash table is a relatively slow operation, so, when
82 * possible, it is a good idea to provide estimates of expected table sizes in
86 * This class and its views and iterators implement all of the
87 * <em>optional</em> methods of the {@link Map} and {@link Iterator} interfaces.
90 * Like {@link Hashtable} but unlike {@link HashMap}, this class does
91 * <em>not</em> allow <tt>null</tt> to be used as a key or value.
94 * This class is a member of the
95 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
96 * Java Collections Framework</a>.
100 * @param <K> the type of keys maintained by this map
101 * @param <V> the type of mapped values
103 public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
104 implements ConcurrentMap<K, V>, Serializable {
106 private static final long serialVersionUID = 7249069246763182397L;
108 * The default initial capacity for this table,
109 * used when not otherwise specified in a constructor.
111 static final int DEFAULT_INITIAL_CAPACITY = 16;
114 * The default load factor for this table, used when not
115 * otherwise specified in a constructor.
117 static final float DEFAULT_LOAD_FACTOR = 0.75f;
120 * The default concurrency level for this table, used when not
121 * otherwise specified in a constructor.
123 static final int DEFAULT_CONCURRENCY_LEVEL = 16;
125 private final Map<K, V> delegate;
129 * Creates a new, empty map with the specified initial
130 * capacity, load factor and concurrency level.
132 * @param initialCapacity the initial capacity. The implementation
133 * performs internal sizing to accommodate this many elements.
134 * @param loadFactor the load factor threshold, used to control resizing.
135 * Resizing may be performed when the average number of elements per
136 * bin exceeds this threshold.
137 * @param concurrencyLevel the estimated number of concurrently
138 * updating threads. The implementation performs internal sizing
139 * to try to accommodate this many threads.
140 * @throws IllegalArgumentException if the initial capacity is
141 * negative or the load factor or concurrencyLevel are
144 @SuppressWarnings("unchecked")
145 public ConcurrentHashMap(int initialCapacity,
146 float loadFactor, int concurrencyLevel) {
147 if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0)
148 throw new IllegalArgumentException();
149 delegate = new HashMap<>(initialCapacity, loadFactor);
153 * Creates a new, empty map with the specified initial capacity
154 * and load factor and with the default concurrencyLevel (16).
156 * @param initialCapacity The implementation performs internal
157 * sizing to accommodate this many elements.
158 * @param loadFactor the load factor threshold, used to control resizing.
159 * Resizing may be performed when the average number of elements per
160 * bin exceeds this threshold.
161 * @throws IllegalArgumentException if the initial capacity of
162 * elements is negative or the load factor is nonpositive
166 public ConcurrentHashMap(int initialCapacity, float loadFactor) {
167 this(initialCapacity, loadFactor, DEFAULT_CONCURRENCY_LEVEL);
171 * Creates a new, empty map with the specified initial capacity,
172 * and with default load factor (0.75) and concurrencyLevel (16).
174 * @param initialCapacity the initial capacity. The implementation
175 * performs internal sizing to accommodate this many elements.
176 * @throws IllegalArgumentException if the initial capacity of
177 * elements is negative.
179 public ConcurrentHashMap(int initialCapacity) {
180 this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
184 * Creates a new, empty map with a default initial capacity (16),
185 * load factor (0.75) and concurrencyLevel (16).
187 public ConcurrentHashMap() {
188 this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
192 * Creates a new map with the same mappings as the given map.
193 * The map is created with a capacity of 1.5 times the number
194 * of mappings in the given map or 16 (whichever is greater),
195 * and a default load factor (0.75) and concurrencyLevel (16).
199 public ConcurrentHashMap(Map<? extends K, ? extends V> m) {
200 this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
201 DEFAULT_INITIAL_CAPACITY),
202 DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
209 return delegate.size();
213 public boolean isEmpty() {
214 return delegate.isEmpty();
218 public boolean containsKey(Object key) {
219 return delegate.containsKey(key);
223 public boolean containsValue(Object value) {
224 return delegate.containsValue(value);
228 public V get(Object key) {
229 return delegate.get(key);
233 public V put(K key, V value) {
234 return delegate.put(key, value);
238 public V remove(Object key) {
239 return delegate.remove(key);
243 public void putAll(Map<? extends K, ? extends V> m) {
248 public void clear() {
253 public Set<K> keySet() {
254 return delegate.keySet();
258 public Collection<V> values() {
259 return delegate.values();
263 public Set<Entry<K, V>> entrySet() {
264 return delegate.entrySet();
268 public boolean equals(Object o) {
269 return delegate.equals(o);
273 public int hashCode() {
274 return delegate.hashCode();
278 public String toString() {
279 return delegate.toString();
283 public V putIfAbsent(K key, V value) {
284 V old = delegate.get(key);
286 return delegate.put(key, value);
292 public boolean remove(Object key, Object value) {
293 if (equals(value, delegate.get(key))) {
294 delegate.remove(key);
302 public boolean replace(K key, V oldValue, V newValue) {
303 if (equals(oldValue, delegate.get(key))) {
304 delegate.put(key, newValue);
312 public V replace(K key, V value) {
313 if (delegate.containsKey(key)) {
314 return delegate.put(key, value);
320 private static boolean equals(Object a, Object b) {