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

java.util.concurrent.ConcurrentHashMap Maven / Gradle / Ivy

There is a newer version: 0.54
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * This file is available under and governed by the GNU General Public
 * License version 2 only, as published by the Free Software Foundation.
 * However, the following notice accompanied the original version of this
 * file:
 *
 * 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/publicdomain/zero/1.0/
 */
package java.util.concurrent;

import java.util.*;
import java.io.Serializable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * A hash table supporting full concurrency of retrievals and adjustable
 * expected concurrency for updates. This class obeys the same functional
 * specification as {@link java.util.Hashtable}, and includes versions of
 * methods corresponding to each method of
 * 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 table in a way that prevents
 * all access. This class is fully interoperable with Hashtable in
 * programs that rely on its thread safety but not on its synchronization
 * details.
 *
 * 

* Retrieval operations (including get) generally do not block, so may * overlap with update operations (including * put and remove). Retrievals reflect the results of the most * recently completed update operations holding upon their onset. For * aggregate operations such as putAll * and clear, concurrent retrievals may reflect insertion or removal of * only some entries. Similarly, Iterators and Enumerations return elements * reflecting the state of the hash table 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 * concurrencyLevel constructor argument (default 16), which * is used as a hint for internal sizing. The table 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 table. 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 table is a relatively slow operation, so, when * possible, it is a good idea to provide estimates of expected table 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 null to be used as a key or value. * *

* This class is a member of the * * Java Collections Framework. * * @since 1.5 * @author Doug Lea * @param the type of keys maintained by this map * @param the type of mapped values */ public class ConcurrentHashMap extends AbstractMap implements ConcurrentMap, Serializable { private static final long serialVersionUID = 7249069246763182397L; /** * The default initial capacity for this table, * used when not otherwise specified in a constructor. */ static final int DEFAULT_INITIAL_CAPACITY = 16; /** * The default load factor for this table, used when not * otherwise specified in a constructor. */ static final float DEFAULT_LOAD_FACTOR = 0.75f; /** * The default concurrency level for this table, used when not * otherwise specified in a constructor. */ static final int DEFAULT_CONCURRENCY_LEVEL = 16; private final Map delegate; /** * Creates a new, empty map with the specified initial * capacity, load factor and concurrency level. * * @param initialCapacity the initial capacity. The implementation * performs internal sizing to accommodate this many elements. * @param loadFactor the load factor threshold, used to control resizing. * Resizing may be performed when the average number of elements per * bin exceeds this threshold. * @param concurrencyLevel the estimated number of concurrently * updating threads. The implementation performs internal sizing * to try to accommodate this many threads. * @throws IllegalArgumentException if the initial capacity is * negative or the load factor or concurrencyLevel are * nonpositive. */ @SuppressWarnings("unchecked") public ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) { if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0) throw new IllegalArgumentException(); delegate = new HashMap<>(initialCapacity, loadFactor); } /** * Creates a new, empty map with the specified initial capacity * and load factor and with the default concurrencyLevel (16). * * @param initialCapacity The implementation performs internal * sizing to accommodate this many elements. * @param loadFactor the load factor threshold, used to control resizing. * Resizing may be performed when the average number of elements per * bin exceeds this threshold. * @throws IllegalArgumentException if the initial capacity of * elements is negative or the load factor is nonpositive * * @since 1.6 */ public ConcurrentHashMap(int initialCapacity, float loadFactor) { this(initialCapacity, loadFactor, DEFAULT_CONCURRENCY_LEVEL); } /** * Creates a new, empty map with the specified initial capacity, * and with default load factor (0.75) and concurrencyLevel (16). * * @param initialCapacity the initial capacity. The implementation * performs internal sizing to accommodate this many elements. * @throws IllegalArgumentException if the initial capacity of * elements is negative. */ public ConcurrentHashMap(int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL); } /** * Creates a new, empty map with a default initial capacity (16), * load factor (0.75) and concurrencyLevel (16). */ public ConcurrentHashMap() { this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL); } /** * Creates a new map with the same mappings as the given map. * The map is created with a capacity of 1.5 times the number * of mappings in the given map or 16 (whichever is greater), * and a default load factor (0.75) and concurrencyLevel (16). * * @param m the map */ public ConcurrentHashMap(Map m) { this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1, DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL); putAll(m); } @Override public int size() { return delegate.size(); } @Override public boolean isEmpty() { return delegate.isEmpty(); } @Override public boolean containsKey(Object key) { return delegate.containsKey(key); } @Override public boolean containsValue(Object value) { return delegate.containsValue(value); } @Override public V get(Object key) { return delegate.get(key); } @Override public V put(K key, V value) { return delegate.put(key, value); } @Override public V remove(Object key) { return delegate.remove(key); } @Override public void putAll(Map m) { delegate.putAll(m); } @Override public void clear() { delegate.clear(); } @Override public Set keySet() { return delegate.keySet(); } @Override public Collection values() { return delegate.values(); } @Override public Set> entrySet() { return delegate.entrySet(); } @Override public boolean equals(Object o) { return delegate.equals(o); } @Override public int hashCode() { return delegate.hashCode(); } @Override public String toString() { return delegate.toString(); } @Override public V putIfAbsent(K key, V value) { V old = delegate.get(key); if (old == null) { return delegate.put(key, value); } return old; } @Override public boolean remove(Object key, Object value) { if (equals(value, delegate.get(key))) { delegate.remove(key); return true; } else { return false; } } @Override public boolean replace(K key, V oldValue, V newValue) { if (equals(oldValue, delegate.get(key))) { delegate.put(key, newValue); return true; } else { return false; } } @Override public V replace(K key, V value) { if (delegate.containsKey(key)) { return delegate.put(key, value); } else { return null; } } private static boolean equals(Object a, Object b) { if (a == null) { return b == null; } else { return a.equals(b); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy