1. /*
  2. * @(#)ConcurrentHashMap.java 1.10 04/07/12
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.util.concurrent;
  8. import java.util.concurrent.locks.*;
  9. import java.util.*;
  10. import java.io.Serializable;
  11. import java.io.IOException;
  12. import java.io.ObjectInputStream;
  13. import java.io.ObjectOutputStream;
  14. /**
  15. * A hash table supporting full concurrency of retrievals and
  16. * adjustable expected concurrency for updates. This class obeys the
  17. * same functional specification as {@link java.util.Hashtable}, and
  18. * includes versions of methods corresponding to each method of
  19. * <tt>Hashtable</tt>. However, even though all operations are
  20. * thread-safe, retrieval operations do <em>not</em> entail locking,
  21. * and there is <em>not</em> any support for locking the entire table
  22. * in a way that prevents all access. This class is fully
  23. * interoperable with <tt>Hashtable</tt> in programs that rely on its
  24. * thread safety but not on its synchronization details.
  25. *
  26. * <p> Retrieval operations (including <tt>get</tt>) generally do not
  27. * block, so may overlap with update operations (including
  28. * <tt>put</tt> and <tt>remove</tt>). Retrievals reflect the results
  29. * of the most recently <em>completed</em> update operations holding
  30. * upon their onset. For aggregate operations such as <tt>putAll</tt>
  31. * and <tt>clear</tt>, concurrent retrievals may reflect insertion or
  32. * removal of only some entries. Similarly, Iterators and
  33. * Enumerations return elements reflecting the state of the hash table
  34. * at some point at or since the creation of the iterator/enumeration.
  35. * They do <em>not</em> throw
  36. * {@link ConcurrentModificationException}. However, iterators are
  37. * designed to be used by only one thread at a time.
  38. *
  39. * <p> The allowed concurrency among update operations is guided by
  40. * the optional <tt>concurrencyLevel</tt> constructor argument
  41. * (default 16), which is used as a hint for internal sizing. The
  42. * table is internally partitioned to try to permit the indicated
  43. * number of concurrent updates without contention. Because placement
  44. * in hash tables is essentially random, the actual concurrency will
  45. * vary. Ideally, you should choose a value to accommodate as many
  46. * threads as will ever concurrently modify the table. Using a
  47. * significantly higher value than you need can waste space and time,
  48. * and a significantly lower value can lead to thread contention. But
  49. * overestimates and underestimates within an order of magnitude do
  50. * not usually have much noticeable impact. A value of one is
  51. * appropriate when it is known that only one thread will modify and
  52. * all others will only read. Also, resizing this or any other kind of
  53. * hash table is a relatively slow operation, so, when possible, it is
  54. * a good idea to provide estimates of expected table sizes in
  55. * constructors.
  56. *
  57. * <p>This class and its views and iterators implement all of the
  58. * <em>optional</em> methods of the {@link Map} and {@link Iterator}
  59. * interfaces.
  60. *
  61. * <p> Like {@link java.util.Hashtable} but unlike {@link
  62. * java.util.HashMap}, this class does NOT allow <tt>null</tt> to be
  63. * used as a key or value.
  64. *
  65. * <p>This class is a member of the
  66. * <a href="{@docRoot}/../guide/collections/index.html">
  67. * Java Collections Framework</a>.
  68. *
  69. * @since 1.5
  70. * @author Doug Lea
  71. * @param <K> the type of keys maintained by this map
  72. * @param <V> the type of mapped values
  73. */
  74. public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
  75. implements ConcurrentMap<K, V>, Serializable {
  76. private static final long serialVersionUID = 7249069246763182397L;
  77. /*
  78. * The basic strategy is to subdivide the table among Segments,
  79. * each of which itself is a concurrently readable hash table.
  80. */
  81. /* ---------------- Constants -------------- */
  82. /**
  83. * The default initial number of table slots for this table.
  84. * Used when not otherwise specified in constructor.
  85. */
  86. static int DEFAULT_INITIAL_CAPACITY = 16;
  87. /**
  88. * The maximum capacity, used if a higher value is implicitly
  89. * specified by either of the constructors with arguments. MUST
  90. * be a power of two <= 1<<30 to ensure that entries are indexible
  91. * using ints.
  92. */
  93. static final int MAXIMUM_CAPACITY = 1 << 30;
  94. /**
  95. * The default load factor for this table. Used when not
  96. * otherwise specified in constructor.
  97. */
  98. static final float DEFAULT_LOAD_FACTOR = 0.75f;
  99. /**
  100. * The default number of concurrency control segments.
  101. **/
  102. static final int DEFAULT_SEGMENTS = 16;
  103. /**
  104. * The maximum number of segments to allow; used to bound
  105. * constructor arguments.
  106. */
  107. static final int MAX_SEGMENTS = 1 << 16; // slightly conservative
  108. /**
  109. * Number of unsynchronized retries in size and containsValue
  110. * methods before resorting to locking. This is used to avoid
  111. * unbounded retries if tables undergo continuous modification
  112. * which would make it impossible to obtain an accurate result.
  113. */
  114. static final int RETRIES_BEFORE_LOCK = 2;
  115. /* ---------------- Fields -------------- */
  116. /**
  117. * Mask value for indexing into segments. The upper bits of a
  118. * key's hash code are used to choose the segment.
  119. **/
  120. final int segmentMask;
  121. /**
  122. * Shift value for indexing within segments.
  123. **/
  124. final int segmentShift;
  125. /**
  126. * The segments, each of which is a specialized hash table
  127. */
  128. final Segment[] segments;
  129. transient Set<K> keySet;
  130. transient Set<Map.Entry<K,V>> entrySet;
  131. transient Collection<V> values;
  132. /* ---------------- Small Utilities -------------- */
  133. /**
  134. * Returns a hash code for non-null Object x.
  135. * Uses the same hash code spreader as most other java.util hash tables.
  136. * @param x the object serving as a key
  137. * @return the hash code
  138. */
  139. static int hash(Object x) {
  140. int h = x.hashCode();
  141. h += ~(h << 9);
  142. h ^= (h >>> 14);
  143. h += (h << 4);
  144. h ^= (h >>> 10);
  145. return h;
  146. }
  147. /**
  148. * Returns the segment that should be used for key with given hash
  149. * @param hash the hash code for the key
  150. * @return the segment
  151. */
  152. final Segment<K,V> segmentFor(int hash) {
  153. return (Segment<K,V>) segments[(hash >>> segmentShift) & segmentMask];
  154. }
  155. /* ---------------- Inner Classes -------------- */
  156. /**
  157. * ConcurrentHashMap list entry. Note that this is never exported
  158. * out as a user-visible Map.Entry.
  159. *
  160. * Because the value field is volatile, not final, it is legal wrt
  161. * the Java Memory Model for an unsynchronized reader to see null
  162. * instead of initial value when read via a data race. Although a
  163. * reordering leading to this is not likely to ever actually
  164. * occur, the Segment.readValueUnderLock method is used as a
  165. * backup in case a null (pre-initialized) value is ever seen in
  166. * an unsynchronized access method.
  167. */
  168. static final class HashEntry<K,V> {
  169. final K key;
  170. final int hash;
  171. volatile V value;
  172. final HashEntry<K,V> next;
  173. HashEntry(K key, int hash, HashEntry<K,V> next, V value) {
  174. this.key = key;
  175. this.hash = hash;
  176. this.next = next;
  177. this.value = value;
  178. }
  179. }
  180. /**
  181. * Segments are specialized versions of hash tables. This
  182. * subclasses from ReentrantLock opportunistically, just to
  183. * simplify some locking and avoid separate construction.
  184. **/
  185. static final class Segment<K,V> extends ReentrantLock implements Serializable {
  186. /*
  187. * Segments maintain a table of entry lists that are ALWAYS
  188. * kept in a consistent state, so can be read without locking.
  189. * Next fields of nodes are immutable (final). All list
  190. * additions are performed at the front of each bin. This
  191. * makes it easy to check changes, and also fast to traverse.
  192. * When nodes would otherwise be changed, new nodes are
  193. * created to replace them. This works well for hash tables
  194. * since the bin lists tend to be short. (The average length
  195. * is less than two for the default load factor threshold.)
  196. *
  197. * Read operations can thus proceed without locking, but rely
  198. * on selected uses of volatiles to ensure that completed
  199. * write operations performed by other threads are
  200. * noticed. For most purposes, the "count" field, tracking the
  201. * number of elements, serves as that volatile variable
  202. * ensuring visibility. This is convenient because this field
  203. * needs to be read in many read operations anyway:
  204. *
  205. * - All (unsynchronized) read operations must first read the
  206. * "count" field, and should not look at table entries if
  207. * it is 0.
  208. *
  209. * - All (synchronized) write operations should write to
  210. * the "count" field after structurally changing any bin.
  211. * The operations must not take any action that could even
  212. * momentarily cause a concurrent read operation to see
  213. * inconsistent data. This is made easier by the nature of
  214. * the read operations in Map. For example, no operation
  215. * can reveal that the table has grown but the threshold
  216. * has not yet been updated, so there are no atomicity
  217. * requirements for this with respect to reads.
  218. *
  219. * As a guide, all critical volatile reads and writes to the
  220. * count field are marked in code comments.
  221. */
  222. private static final long serialVersionUID = 2249069246763182397L;
  223. /**
  224. * The number of elements in this segment's region.
  225. **/
  226. transient volatile int count;
  227. /**
  228. * Number of updates that alter the size of the table. This is
  229. * used during bulk-read methods to make sure they see a
  230. * consistent snapshot: If modCounts change during a traversal
  231. * of segments computing size or checking containsValue, then
  232. * we might have an inconsistent view of state so (usually)
  233. * must retry.
  234. */
  235. transient int modCount;
  236. /**
  237. * The table is rehashed when its size exceeds this threshold.
  238. * (The value of this field is always (int)(capacity *
  239. * loadFactor).)
  240. */
  241. transient int threshold;
  242. /**
  243. * The per-segment table. Declared as a raw type, casted
  244. * to HashEntry<K,V> on each use.
  245. */
  246. transient volatile HashEntry[] table;
  247. /**
  248. * The load factor for the hash table. Even though this value
  249. * is same for all segments, it is replicated to avoid needing
  250. * links to outer object.
  251. * @serial
  252. */
  253. final float loadFactor;
  254. Segment(int initialCapacity, float lf) {
  255. loadFactor = lf;
  256. setTable(new HashEntry[initialCapacity]);
  257. }
  258. /**
  259. * Set table to new HashEntry array.
  260. * Call only while holding lock or in constructor.
  261. **/
  262. void setTable(HashEntry[] newTable) {
  263. threshold = (int)(newTable.length * loadFactor);
  264. table = newTable;
  265. }
  266. /**
  267. * Return properly casted first entry of bin for given hash
  268. */
  269. HashEntry<K,V> getFirst(int hash) {
  270. HashEntry[] tab = table;
  271. return (HashEntry<K,V>) tab[hash & (tab.length - 1)];
  272. }
  273. /**
  274. * Read value field of an entry under lock. Called if value
  275. * field ever appears to be null. This is possible only if a
  276. * compiler happens to reorder a HashEntry initialization with
  277. * its table assignment, which is legal under memory model
  278. * but is not known to ever occur.
  279. */
  280. V readValueUnderLock(HashEntry<K,V> e) {
  281. lock();
  282. try {
  283. return e.value;
  284. } finally {
  285. unlock();
  286. }
  287. }
  288. /* Specialized implementations of map methods */
  289. V get(Object key, int hash) {
  290. if (count != 0) { // read-volatile
  291. HashEntry<K,V> e = getFirst(hash);
  292. while (e != null) {
  293. if (e.hash == hash && key.equals(e.key)) {
  294. V v = e.value;
  295. if (v != null)
  296. return v;
  297. return readValueUnderLock(e); // recheck
  298. }
  299. e = e.next;
  300. }
  301. }
  302. return null;
  303. }
  304. boolean containsKey(Object key, int hash) {
  305. if (count != 0) { // read-volatile
  306. HashEntry<K,V> e = getFirst(hash);
  307. while (e != null) {
  308. if (e.hash == hash && key.equals(e.key))
  309. return true;
  310. e = e.next;
  311. }
  312. }
  313. return false;
  314. }
  315. boolean containsValue(Object value) {
  316. if (count != 0) { // read-volatile
  317. HashEntry[] tab = table;
  318. int len = tab.length;
  319. for (int i = 0 ; i < len; i++) {
  320. for (HashEntry<K,V> e = (HashEntry<K,V>)tab[i];
  321. e != null ;
  322. e = e.next) {
  323. V v = e.value;
  324. if (v == null) // recheck
  325. v = readValueUnderLock(e);
  326. if (value.equals(v))
  327. return true;
  328. }
  329. }
  330. }
  331. return false;
  332. }
  333. boolean replace(K key, int hash, V oldValue, V newValue) {
  334. lock();
  335. try {
  336. HashEntry<K,V> e = getFirst(hash);
  337. while (e != null && (e.hash != hash || !key.equals(e.key)))
  338. e = e.next;
  339. boolean replaced = false;
  340. if (e != null && oldValue.equals(e.value)) {
  341. replaced = true;
  342. e.value = newValue;
  343. }
  344. return replaced;
  345. } finally {
  346. unlock();
  347. }
  348. }
  349. V replace(K key, int hash, V newValue) {
  350. lock();
  351. try {
  352. HashEntry<K,V> e = getFirst(hash);
  353. while (e != null && (e.hash != hash || !key.equals(e.key)))
  354. e = e.next;
  355. V oldValue = null;
  356. if (e != null) {
  357. oldValue = e.value;
  358. e.value = newValue;
  359. }
  360. return oldValue;
  361. } finally {
  362. unlock();
  363. }
  364. }
  365. V put(K key, int hash, V value, boolean onlyIfAbsent) {
  366. lock();
  367. try {
  368. int c = count;
  369. if (c++ > threshold) // ensure capacity
  370. rehash();
  371. HashEntry[] tab = table;
  372. int index = hash & (tab.length - 1);
  373. HashEntry<K,V> first = (HashEntry<K,V>) tab[index];
  374. HashEntry<K,V> e = first;
  375. while (e != null && (e.hash != hash || !key.equals(e.key)))
  376. e = e.next;
  377. V oldValue;
  378. if (e != null) {
  379. oldValue = e.value;
  380. if (!onlyIfAbsent)
  381. e.value = value;
  382. }
  383. else {
  384. oldValue = null;
  385. ++modCount;
  386. tab[index] = new HashEntry<K,V>(key, hash, first, value);
  387. count = c; // write-volatile
  388. }
  389. return oldValue;
  390. } finally {
  391. unlock();
  392. }
  393. }
  394. void rehash() {
  395. HashEntry[] oldTable = table;
  396. int oldCapacity = oldTable.length;
  397. if (oldCapacity >= MAXIMUM_CAPACITY)
  398. return;
  399. /*
  400. * Reclassify nodes in each list to new Map. Because we are
  401. * using power-of-two expansion, the elements from each bin
  402. * must either stay at same index, or move with a power of two
  403. * offset. We eliminate unnecessary node creation by catching
  404. * cases where old nodes can be reused because their next
  405. * fields won't change. Statistically, at the default
  406. * threshold, only about one-sixth of them need cloning when
  407. * a table doubles. The nodes they replace will be garbage
  408. * collectable as soon as they are no longer referenced by any
  409. * reader thread that may be in the midst of traversing table
  410. * right now.
  411. */
  412. HashEntry[] newTable = new HashEntry[oldCapacity << 1];
  413. threshold = (int)(newTable.length * loadFactor);
  414. int sizeMask = newTable.length - 1;
  415. for (int i = 0; i < oldCapacity ; i++) {
  416. // We need to guarantee that any existing reads of old Map can
  417. // proceed. So we cannot yet null out each bin.
  418. HashEntry<K,V> e = (HashEntry<K,V>)oldTable[i];
  419. if (e != null) {
  420. HashEntry<K,V> next = e.next;
  421. int idx = e.hash & sizeMask;
  422. // Single node on list
  423. if (next == null)
  424. newTable[idx] = e;
  425. else {
  426. // Reuse trailing consecutive sequence at same slot
  427. HashEntry<K,V> lastRun = e;
  428. int lastIdx = idx;
  429. for (HashEntry<K,V> last = next;
  430. last != null;
  431. last = last.next) {
  432. int k = last.hash & sizeMask;
  433. if (k != lastIdx) {
  434. lastIdx = k;
  435. lastRun = last;
  436. }
  437. }
  438. newTable[lastIdx] = lastRun;
  439. // Clone all remaining nodes
  440. for (HashEntry<K,V> p = e; p != lastRun; p = p.next) {
  441. int k = p.hash & sizeMask;
  442. HashEntry<K,V> n = (HashEntry<K,V>)newTable[k];
  443. newTable[k] = new HashEntry<K,V>(p.key, p.hash,
  444. n, p.value);
  445. }
  446. }
  447. }
  448. }
  449. table = newTable;
  450. }
  451. /**
  452. * Remove; match on key only if value null, else match both.
  453. */
  454. V remove(Object key, int hash, Object value) {
  455. lock();
  456. try {
  457. int c = count - 1;
  458. HashEntry[] tab = table;
  459. int index = hash & (tab.length - 1);
  460. HashEntry<K,V> first = (HashEntry<K,V>)tab[index];
  461. HashEntry<K,V> e = first;
  462. while (e != null && (e.hash != hash || !key.equals(e.key)))
  463. e = e.next;
  464. V oldValue = null;
  465. if (e != null) {
  466. V v = e.value;
  467. if (value == null || value.equals(v)) {
  468. oldValue = v;
  469. // All entries following removed node can stay
  470. // in list, but all preceding ones need to be
  471. // cloned.
  472. ++modCount;
  473. HashEntry<K,V> newFirst = e.next;
  474. for (HashEntry<K,V> p = first; p != e; p = p.next)
  475. newFirst = new HashEntry<K,V>(p.key, p.hash,
  476. newFirst, p.value);
  477. tab[index] = newFirst;
  478. count = c; // write-volatile
  479. }
  480. }
  481. return oldValue;
  482. } finally {
  483. unlock();
  484. }
  485. }
  486. void clear() {
  487. if (count != 0) {
  488. lock();
  489. try {
  490. HashEntry[] tab = table;
  491. for (int i = 0; i < tab.length ; i++)
  492. tab[i] = null;
  493. ++modCount;
  494. count = 0; // write-volatile
  495. } finally {
  496. unlock();
  497. }
  498. }
  499. }
  500. }
  501. /* ---------------- Public operations -------------- */
  502. /**
  503. * Creates a new, empty map with the specified initial
  504. * capacity, load factor, and concurrency level.
  505. *
  506. * @param initialCapacity the initial capacity. The implementation
  507. * performs internal sizing to accommodate this many elements.
  508. * @param loadFactor the load factor threshold, used to control resizing.
  509. * Resizing may be performed when the average number of elements per
  510. * bin exceeds this threshold.
  511. * @param concurrencyLevel the estimated number of concurrently
  512. * updating threads. The implementation performs internal sizing
  513. * to try to accommodate this many threads.
  514. * @throws IllegalArgumentException if the initial capacity is
  515. * negative or the load factor or concurrencyLevel are
  516. * nonpositive.
  517. */
  518. public ConcurrentHashMap(int initialCapacity,
  519. float loadFactor, int concurrencyLevel) {
  520. if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0)
  521. throw new IllegalArgumentException();
  522. if (concurrencyLevel > MAX_SEGMENTS)
  523. concurrencyLevel = MAX_SEGMENTS;
  524. // Find power-of-two sizes best matching arguments
  525. int sshift = 0;
  526. int ssize = 1;
  527. while (ssize < concurrencyLevel) {
  528. ++sshift;
  529. ssize <<= 1;
  530. }
  531. segmentShift = 32 - sshift;
  532. segmentMask = ssize - 1;
  533. this.segments = new Segment[ssize];
  534. if (initialCapacity > MAXIMUM_CAPACITY)
  535. initialCapacity = MAXIMUM_CAPACITY;
  536. int c = initialCapacity / ssize;
  537. if (c * ssize < initialCapacity)
  538. ++c;
  539. int cap = 1;
  540. while (cap < c)
  541. cap <<= 1;
  542. for (int i = 0; i < this.segments.length; ++i)
  543. this.segments[i] = new Segment<K,V>(cap, loadFactor);
  544. }
  545. /**
  546. * Creates a new, empty map with the specified initial
  547. * capacity, and with default load factor and concurrencyLevel.
  548. *
  549. * @param initialCapacity the initial capacity. The implementation
  550. * performs internal sizing to accommodate this many elements.
  551. * @throws IllegalArgumentException if the initial capacity of
  552. * elements is negative.
  553. */
  554. public ConcurrentHashMap(int initialCapacity) {
  555. this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
  556. }
  557. /**
  558. * Creates a new, empty map with a default initial capacity,
  559. * load factor, and concurrencyLevel.
  560. */
  561. public ConcurrentHashMap() {
  562. this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
  563. }
  564. /**
  565. * Creates a new map with the same mappings as the given map. The
  566. * map is created with a capacity of twice the number of mappings in
  567. * the given map or 11 (whichever is greater), and a default load factor
  568. * and concurrencyLevel.
  569. * @param t the map
  570. */
  571. public ConcurrentHashMap(Map<? extends K, ? extends V> t) {
  572. this(Math.max((int) (t.size() / DEFAULT_LOAD_FACTOR) + 1,
  573. 11),
  574. DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
  575. putAll(t);
  576. }
  577. // inherit Map javadoc
  578. public boolean isEmpty() {
  579. final Segment[] segments = this.segments;
  580. /*
  581. * We keep track of per-segment modCounts to avoid ABA
  582. * problems in which an element in one segment was added and
  583. * in another removed during traversal, in which case the
  584. * table was never actually empty at any point. Note the
  585. * similar use of modCounts in the size() and containsValue()
  586. * methods, which are the only other methods also susceptible
  587. * to ABA problems.
  588. */
  589. int[] mc = new int[segments.length];
  590. int mcsum = 0;
  591. for (int i = 0; i < segments.length; ++i) {
  592. if (segments[i].count != 0)
  593. return false;
  594. else
  595. mcsum += mc[i] = segments[i].modCount;
  596. }
  597. // If mcsum happens to be zero, then we know we got a snapshot
  598. // before any modifications at all were made. This is
  599. // probably common enough to bother tracking.
  600. if (mcsum != 0) {
  601. for (int i = 0; i < segments.length; ++i) {
  602. if (segments[i].count != 0 ||
  603. mc[i] != segments[i].modCount)
  604. return false;
  605. }
  606. }
  607. return true;
  608. }
  609. // inherit Map javadoc
  610. public int size() {
  611. final Segment[] segments = this.segments;
  612. long sum = 0;
  613. long check = 0;
  614. int[] mc = new int[segments.length];
  615. // Try a few times to get accurate count. On failure due to
  616. // continuous async changes in table, resort to locking.
  617. for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) {
  618. check = 0;
  619. sum = 0;
  620. int mcsum = 0;
  621. for (int i = 0; i < segments.length; ++i) {
  622. sum += segments[i].count;
  623. mcsum += mc[i] = segments[i].modCount;
  624. }
  625. if (mcsum != 0) {
  626. for (int i = 0; i < segments.length; ++i) {
  627. check += segments[i].count;
  628. if (mc[i] != segments[i].modCount) {
  629. check = -1; // force retry
  630. break;
  631. }
  632. }
  633. }
  634. if (check == sum)
  635. break;
  636. }
  637. if (check != sum) { // Resort to locking all segments
  638. sum = 0;
  639. for (int i = 0; i < segments.length; ++i)
  640. segments[i].lock();
  641. for (int i = 0; i < segments.length; ++i)
  642. sum += segments[i].count;
  643. for (int i = 0; i < segments.length; ++i)
  644. segments[i].unlock();
  645. }
  646. if (sum > Integer.MAX_VALUE)
  647. return Integer.MAX_VALUE;
  648. else
  649. return (int)sum;
  650. }
  651. /**
  652. * Returns the value to which the specified key is mapped in this table.
  653. *
  654. * @param key a key in the table.
  655. * @return the value to which the key is mapped in this table;
  656. * <tt>null</tt> if the key is not mapped to any value in
  657. * this table.
  658. * @throws NullPointerException if the key is
  659. * <tt>null</tt>.
  660. */
  661. public V get(Object key) {
  662. int hash = hash(key); // throws NullPointerException if key null
  663. return segmentFor(hash).get(key, hash);
  664. }
  665. /**
  666. * Tests if the specified object is a key in this table.
  667. *
  668. * @param key possible key.
  669. * @return <tt>true</tt> if and only if the specified object
  670. * is a key in this table, as determined by the
  671. * <tt>equals</tt> method; <tt>false</tt> otherwise.
  672. * @throws NullPointerException if the key is
  673. * <tt>null</tt>.
  674. */
  675. public boolean containsKey(Object key) {
  676. int hash = hash(key); // throws NullPointerException if key null
  677. return segmentFor(hash).containsKey(key, hash);
  678. }
  679. /**
  680. * Returns <tt>true</tt> if this map maps one or more keys to the
  681. * specified value. Note: This method requires a full internal
  682. * traversal of the hash table, and so is much slower than
  683. * method <tt>containsKey</tt>.
  684. *
  685. * @param value value whose presence in this map is to be tested.
  686. * @return <tt>true</tt> if this map maps one or more keys to the
  687. * specified value.
  688. * @throws NullPointerException if the value is <tt>null</tt>.
  689. */
  690. public boolean containsValue(Object value) {
  691. if (value == null)
  692. throw new NullPointerException();
  693. // See explanation of modCount use above
  694. final Segment[] segments = this.segments;
  695. int[] mc = new int[segments.length];
  696. // Try a few times without locking
  697. for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) {
  698. int sum = 0;
  699. int mcsum = 0;
  700. for (int i = 0; i < segments.length; ++i) {
  701. int c = segments[i].count;
  702. mcsum += mc[i] = segments[i].modCount;
  703. if (segments[i].containsValue(value))
  704. return true;
  705. }
  706. boolean cleanSweep = true;
  707. if (mcsum != 0) {
  708. for (int i = 0; i < segments.length; ++i) {
  709. int c = segments[i].count;
  710. if (mc[i] != segments[i].modCount) {
  711. cleanSweep = false;
  712. break;
  713. }
  714. }
  715. }
  716. if (cleanSweep)
  717. return false;
  718. }
  719. // Resort to locking all segments
  720. for (int i = 0; i < segments.length; ++i)
  721. segments[i].lock();
  722. boolean found = false;
  723. try {
  724. for (int i = 0; i < segments.length; ++i) {
  725. if (segments[i].containsValue(value)) {
  726. found = true;
  727. break;
  728. }
  729. }
  730. } finally {
  731. for (int i = 0; i < segments.length; ++i)
  732. segments[i].unlock();
  733. }
  734. return found;
  735. }
  736. /**
  737. * Legacy method testing if some key maps into the specified value
  738. * in this table. This method is identical in functionality to
  739. * {@link #containsValue}, and exists solely to ensure
  740. * full compatibility with class {@link java.util.Hashtable},
  741. * which supported this method prior to introduction of the
  742. * Java Collections framework.
  743. * @param value a value to search for.
  744. * @return <tt>true</tt> if and only if some key maps to the
  745. * <tt>value</tt> argument in this table as
  746. * determined by the <tt>equals</tt> method;
  747. * <tt>false</tt> otherwise.
  748. * @throws NullPointerException if the value is <tt>null</tt>.
  749. */
  750. public boolean contains(Object value) {
  751. return containsValue(value);
  752. }
  753. /**
  754. * Maps the specified <tt>key</tt> to the specified
  755. * <tt>value</tt> in this table. Neither the key nor the
  756. * value can be <tt>null</tt>.
  757. *
  758. * <p> The value can be retrieved by calling the <tt>get</tt> method
  759. * with a key that is equal to the original key.
  760. *
  761. * @param key the table key.
  762. * @param value the value.
  763. * @return the previous value of the specified key in this table,
  764. * or <tt>null</tt> if it did not have one.
  765. * @throws NullPointerException if the key or value is
  766. * <tt>null</tt>.
  767. */
  768. public V put(K key, V value) {
  769. if (value == null)
  770. throw new NullPointerException();
  771. int hash = hash(key);
  772. return segmentFor(hash).put(key, hash, value, false);
  773. }
  774. /**
  775. * If the specified key is not already associated
  776. * with a value, associate it with the given value.
  777. * This is equivalent to
  778. * <pre>
  779. * if (!map.containsKey(key))
  780. * return map.put(key, value);
  781. * else
  782. * return map.get(key);
  783. * </pre>
  784. * Except that the action is performed atomically.
  785. * @param key key with which the specified value is to be associated.
  786. * @param value value to be associated with the specified key.
  787. * @return previous value associated with specified key, or <tt>null</tt>
  788. * if there was no mapping for key.
  789. * @throws NullPointerException if the specified key or value is
  790. * <tt>null</tt>.
  791. */
  792. public V putIfAbsent(K key, V value) {
  793. if (value == null)
  794. throw new NullPointerException();
  795. int hash = hash(key);
  796. return segmentFor(hash).put(key, hash, value, true);
  797. }
  798. /**
  799. * Copies all of the mappings from the specified map to this one.
  800. *
  801. * These mappings replace any mappings that this map had for any of the
  802. * keys currently in the specified Map.
  803. *
  804. * @param t Mappings to be stored in this map.
  805. */
  806. public void putAll(Map<? extends K, ? extends V> t) {
  807. for (Iterator<? extends Map.Entry<? extends K, ? extends V>> it = (Iterator<? extends Map.Entry<? extends K, ? extends V>>) t.entrySet().iterator(); it.hasNext(); ) {
  808. Entry<? extends K, ? extends V> e = it.next();
  809. put(e.getKey(), e.getValue());
  810. }
  811. }
  812. /**
  813. * Removes the key (and its corresponding value) from this
  814. * table. This method does nothing if the key is not in the table.
  815. *
  816. * @param key the key that needs to be removed.
  817. * @return the value to which the key had been mapped in this table,
  818. * or <tt>null</tt> if the key did not have a mapping.
  819. * @throws NullPointerException if the key is
  820. * <tt>null</tt>.
  821. */
  822. public V remove(Object key) {
  823. int hash = hash(key);
  824. return segmentFor(hash).remove(key, hash, null);
  825. }
  826. /**
  827. * Remove entry for key only if currently mapped to given value.
  828. * Acts as
  829. * <pre>
  830. * if (map.get(key).equals(value)) {
  831. * map.remove(key);
  832. * return true;
  833. * } else return false;
  834. * </pre>
  835. * except that the action is performed atomically.
  836. * @param key key with which the specified value is associated.
  837. * @param value value associated with the specified key.
  838. * @return true if the value was removed
  839. * @throws NullPointerException if the specified key is
  840. * <tt>null</tt>.
  841. */
  842. public boolean remove(Object key, Object value) {
  843. int hash = hash(key);
  844. return segmentFor(hash).remove(key, hash, value) != null;
  845. }
  846. /**
  847. * Replace entry for key only if currently mapped to given value.
  848. * Acts as
  849. * <pre>
  850. * if (map.get(key).equals(oldValue)) {
  851. * map.put(key, newValue);
  852. * return true;
  853. * } else return false;
  854. * </pre>
  855. * except that the action is performed atomically.
  856. * @param key key with which the specified value is associated.
  857. * @param oldValue value expected to be associated with the specified key.
  858. * @param newValue value to be associated with the specified key.
  859. * @return true if the value was replaced
  860. * @throws NullPointerException if the specified key or values are
  861. * <tt>null</tt>.
  862. */
  863. public boolean replace(K key, V oldValue, V newValue) {
  864. if (oldValue == null || newValue == null)
  865. throw new NullPointerException();
  866. int hash = hash(key);
  867. return segmentFor(hash).replace(key, hash, oldValue, newValue);
  868. }
  869. /**
  870. * Replace entry for key only if currently mapped to some value.
  871. * Acts as
  872. * <pre>
  873. * if ((map.containsKey(key)) {
  874. * return map.put(key, value);
  875. * } else return null;
  876. * </pre>
  877. * except that the action is performed atomically.
  878. * @param key key with which the specified value is associated.
  879. * @param value value to be associated with the specified key.
  880. * @return previous value associated with specified key, or <tt>null</tt>
  881. * if there was no mapping for key.
  882. * @throws NullPointerException if the specified key or value is
  883. * <tt>null</tt>.
  884. */
  885. public V replace(K key, V value) {
  886. if (value == null)
  887. throw new NullPointerException();
  888. int hash = hash(key);
  889. return segmentFor(hash).replace(key, hash, value);
  890. }
  891. /**
  892. * Removes all mappings from this map.
  893. */
  894. public void clear() {
  895. for (int i = 0; i < segments.length; ++i)
  896. segments[i].clear();
  897. }
  898. /**
  899. * Returns a set view of the keys contained in this map. The set is
  900. * backed by the map, so changes to the map are reflected in the set, and
  901. * vice-versa. The set supports element removal, which removes the
  902. * corresponding mapping from this map, via the <tt>Iterator.remove</tt>,
  903. * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
  904. * <tt>clear</tt> operations. It does not support the <tt>add</tt> or
  905. * <tt>addAll</tt> operations.
  906. * The view's returned <tt>iterator</tt> is a "weakly consistent" iterator that
  907. * will never throw {@link java.util.ConcurrentModificationException},
  908. * and guarantees to traverse elements as they existed upon
  909. * construction of the iterator, and may (but is not guaranteed to)
  910. * reflect any modifications subsequent to construction.
  911. *
  912. * @return a set view of the keys contained in this map.
  913. */
  914. public Set<K> keySet() {
  915. Set<K> ks = keySet;
  916. return (ks != null) ? ks : (keySet = new KeySet());
  917. }
  918. /**
  919. * Returns a collection view of the values contained in this map. The
  920. * collection is backed by the map, so changes to the map are reflected in
  921. * the collection, and vice-versa. The collection supports element
  922. * removal, which removes the corresponding mapping from this map, via the
  923. * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
  924. * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
  925. * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
  926. * The view's returned <tt>iterator</tt> is a "weakly consistent" iterator that
  927. * will never throw {@link java.util.ConcurrentModificationException},
  928. * and guarantees to traverse elements as they existed upon
  929. * construction of the iterator, and may (but is not guaranteed to)
  930. * reflect any modifications subsequent to construction.
  931. *
  932. * @return a collection view of the values contained in this map.
  933. */
  934. public Collection<V> values() {
  935. Collection<V> vs = values;
  936. return (vs != null) ? vs : (values = new Values());
  937. }
  938. /**
  939. * Returns a collection view of the mappings contained in this map. Each
  940. * element in the returned collection is a <tt>Map.Entry</tt>. The
  941. * collection is backed by the map, so changes to the map are reflected in
  942. * the collection, and vice-versa. The collection supports element
  943. * removal, which removes the corresponding mapping from the map, via the
  944. * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
  945. * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
  946. * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
  947. * The view's returned <tt>iterator</tt> is a "weakly consistent" iterator that
  948. * will never throw {@link java.util.ConcurrentModificationException},
  949. * and guarantees to traverse elements as they existed upon
  950. * construction of the iterator, and may (but is not guaranteed to)
  951. * reflect any modifications subsequent to construction.
  952. *
  953. * @return a collection view of the mappings contained in this map.
  954. */
  955. public Set<Map.Entry<K,V>> entrySet() {
  956. Set<Map.Entry<K,V>> es = entrySet;
  957. return (es != null) ? es : (entrySet = (Set<Map.Entry<K,V>>) (Set) new EntrySet());
  958. }
  959. /**
  960. * Returns an enumeration of the keys in this table.
  961. *
  962. * @return an enumeration of the keys in this table.
  963. * @see #keySet
  964. */
  965. public Enumeration<K> keys() {
  966. return new KeyIterator();
  967. }
  968. /**
  969. * Returns an enumeration of the values in this table.
  970. *
  971. * @return an enumeration of the values in this table.
  972. * @see #values
  973. */
  974. public Enumeration<V> elements() {
  975. return new ValueIterator();
  976. }
  977. /* ---------------- Iterator Support -------------- */
  978. abstract class HashIterator {
  979. int nextSegmentIndex;
  980. int nextTableIndex;
  981. HashEntry[] currentTable;
  982. HashEntry<K, V> nextEntry;
  983. HashEntry<K, V> lastReturned;
  984. HashIterator() {
  985. nextSegmentIndex = segments.length - 1;
  986. nextTableIndex = -1;
  987. advance();
  988. }
  989. public boolean hasMoreElements() { return hasNext(); }
  990. final void advance() {
  991. if (nextEntry != null && (nextEntry = nextEntry.next) != null)
  992. return;
  993. while (nextTableIndex >= 0) {
  994. if ( (nextEntry = (HashEntry<K,V>)currentTable[nextTableIndex--]) != null)
  995. return;
  996. }
  997. while (nextSegmentIndex >= 0) {
  998. Segment<K,V> seg = (Segment<K,V>)segments[nextSegmentIndex--];
  999. if (seg.count != 0) {
  1000. currentTable = seg.table;
  1001. for (int j = currentTable.length - 1; j >= 0; --j) {
  1002. if ( (nextEntry = (HashEntry<K,V>)currentTable[j]) != null) {
  1003. nextTableIndex = j - 1;
  1004. return;
  1005. }
  1006. }
  1007. }
  1008. }
  1009. }
  1010. public boolean hasNext() { return nextEntry != null; }
  1011. HashEntry<K,V> nextEntry() {
  1012. if (nextEntry == null)
  1013. throw new NoSuchElementException();
  1014. lastReturned = nextEntry;
  1015. advance();
  1016. return lastReturned;
  1017. }
  1018. public void remove() {
  1019. if (lastReturned == null)
  1020. throw new IllegalStateException();
  1021. ConcurrentHashMap.this.remove(lastReturned.key);
  1022. lastReturned = null;
  1023. }
  1024. }
  1025. final class KeyIterator extends HashIterator implements Iterator<K>, Enumeration<K> {
  1026. public K next() { return super.nextEntry().key; }
  1027. public K nextElement() { return super.nextEntry().key; }
  1028. }
  1029. final class ValueIterator extends HashIterator implements Iterator<V>, Enumeration<V> {
  1030. public V next() { return super.nextEntry().value; }
  1031. public V nextElement() { return super.nextEntry().value; }
  1032. }
  1033. /**
  1034. * Entry iterator. Exported Entry objects must write-through
  1035. * changes in setValue, even if the nodes have been cloned. So we
  1036. * cannot return internal HashEntry objects. Instead, the iterator
  1037. * itself acts as a forwarding pseudo-entry.
  1038. */
  1039. final class EntryIterator extends HashIterator implements Map.Entry<K,V>, Iterator<Entry<K,V>> {
  1040. public Map.Entry<K,V> next() {
  1041. nextEntry();
  1042. return this;
  1043. }
  1044. public K getKey() {
  1045. if (lastReturned == null)
  1046. throw new IllegalStateException("Entry was removed");
  1047. return lastReturned.key;
  1048. }
  1049. public V getValue() {
  1050. if (lastReturned == null)
  1051. throw new IllegalStateException("Entry was removed");
  1052. return ConcurrentHashMap.this.get(lastReturned.key);
  1053. }
  1054. public V setValue(V value) {
  1055. if (lastReturned == null)
  1056. throw new IllegalStateException("Entry was removed");
  1057. return ConcurrentHashMap.this.put(lastReturned.key, value);
  1058. }
  1059. public boolean equals(Object o) {
  1060. // If not acting as entry, just use default.
  1061. if (lastReturned == null)
  1062. return super.equals(o);
  1063. if (!(o instanceof Map.Entry))
  1064. return false;
  1065. Map.Entry e = (Map.Entry)o;
  1066. return eq(getKey(), e.getKey()) && eq(getValue(), e.getValue());
  1067. }
  1068. public int hashCode() {
  1069. // If not acting as entry, just use default.
  1070. if (lastReturned == null)
  1071. return super.hashCode();
  1072. Object k = getKey();
  1073. Object v = getValue();
  1074. return ((k == null) ? 0 : k.hashCode()) ^
  1075. ((v == null) ? 0 : v.hashCode());
  1076. }
  1077. public String toString() {
  1078. // If not acting as entry, just use default.
  1079. if (lastReturned == null)
  1080. return super.toString();
  1081. else
  1082. return getKey() + "=" + getValue();
  1083. }
  1084. boolean eq(Object o1, Object o2) {
  1085. return (o1 == null ? o2 == null : o1.equals(o2));
  1086. }
  1087. }
  1088. final class KeySet extends AbstractSet<K> {
  1089. public Iterator<K> iterator() {
  1090. return new KeyIterator();
  1091. }
  1092. public int size() {
  1093. return ConcurrentHashMap.this.size();
  1094. }
  1095. public boolean contains(Object o) {
  1096. return ConcurrentHashMap.this.containsKey(o);
  1097. }
  1098. public boolean remove(Object o) {
  1099. return ConcurrentHashMap.this.remove(o) != null;
  1100. }
  1101. public void clear() {
  1102. ConcurrentHashMap.this.clear();
  1103. }
  1104. public Object[] toArray() {
  1105. Collection<K> c = new ArrayList<K>();
  1106. for (Iterator<K> i = iterator(); i.hasNext(); )
  1107. c.add(i.next());
  1108. return c.toArray();
  1109. }
  1110. public <T> T[] toArray(T[] a) {
  1111. Collection<K> c = new ArrayList<K>();
  1112. for (Iterator<K> i = iterator(); i.hasNext(); )
  1113. c.add(i.next());
  1114. return c.toArray(a);
  1115. }
  1116. }
  1117. final class Values extends AbstractCollection<V> {
  1118. public Iterator<V> iterator() {
  1119. return new ValueIterator();
  1120. }
  1121. public int size() {
  1122. return ConcurrentHashMap.this.size();
  1123. }
  1124. public boolean contains(Object o) {
  1125. return ConcurrentHashMap.this.containsValue(o);
  1126. }
  1127. public void clear() {
  1128. ConcurrentHashMap.this.clear();
  1129. }
  1130. public Object[] toArray() {
  1131. Collection<V> c = new ArrayList<V>();
  1132. for (Iterator<V> i = iterator(); i.hasNext(); )
  1133. c.add(i.next());
  1134. return c.toArray();
  1135. }
  1136. public <T> T[] toArray(T[] a) {
  1137. Collection<V> c = new ArrayList<V>();
  1138. for (Iterator<V> i = iterator(); i.hasNext(); )
  1139. c.add(i.next());
  1140. return c.toArray(a);
  1141. }
  1142. }
  1143. final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
  1144. public Iterator<Map.Entry<K,V>> iterator() {
  1145. return new EntryIterator();
  1146. }
  1147. public boolean contains(Object o) {
  1148. if (!(o instanceof Map.Entry))
  1149. return false;
  1150. Map.Entry<K,V> e = (Map.Entry<K,V>)o;
  1151. V v = ConcurrentHashMap.this.get(e.getKey());
  1152. return v != null && v.equals(e.getValue());
  1153. }
  1154. public boolean remove(Object o) {
  1155. if (!(o instanceof Map.Entry))
  1156. return false;
  1157. Map.Entry<K,V> e = (Map.Entry<K,V>)o;
  1158. return ConcurrentHashMap.this.remove(e.getKey(), e.getValue());
  1159. }
  1160. public int size() {
  1161. return ConcurrentHashMap.this.size();
  1162. }
  1163. public void clear() {
  1164. ConcurrentHashMap.this.clear();
  1165. }
  1166. public Object[] toArray() {
  1167. // Since we don't ordinarily have distinct Entry objects, we
  1168. // must pack elements using exportable SimpleEntry
  1169. Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(size());
  1170. for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); )
  1171. c.add(new SimpleEntry<K,V>(i.next()));
  1172. return c.toArray();
  1173. }
  1174. public <T> T[] toArray(T[] a) {
  1175. Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(size());
  1176. for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); )
  1177. c.add(new SimpleEntry<K,V>(i.next()));
  1178. return c.toArray(a);
  1179. }
  1180. }
  1181. /**
  1182. * This duplicates java.util.AbstractMap.SimpleEntry until this class
  1183. * is made accessible.
  1184. */
  1185. static final class SimpleEntry<K,V> implements Entry<K,V> {
  1186. K key;
  1187. V value;
  1188. public SimpleEntry(K key, V value) {
  1189. this.key = key;
  1190. this.value = value;
  1191. }
  1192. public SimpleEntry(Entry<K,V> e) {
  1193. this.key = e.getKey();
  1194. this.value = e.getValue();
  1195. }
  1196. public K getKey() {
  1197. return key;
  1198. }
  1199. public V getValue() {
  1200. return value;
  1201. }
  1202. public V setValue(V value) {
  1203. V oldValue = this.value;
  1204. this.value = value;
  1205. return oldValue;
  1206. }
  1207. public boolean equals(Object o) {
  1208. if (!(o instanceof Map.Entry))
  1209. return false;
  1210. Map.Entry e = (Map.Entry)o;
  1211. return eq(key, e.getKey()) && eq(value, e.getValue());
  1212. }
  1213. public int hashCode() {
  1214. return ((key == null) ? 0 : key.hashCode()) ^
  1215. ((value == null) ? 0 : value.hashCode());
  1216. }
  1217. public String toString() {
  1218. return key + "=" + value;
  1219. }
  1220. static boolean eq(Object o1, Object o2) {
  1221. return (o1 == null ? o2 == null : o1.equals(o2));
  1222. }
  1223. }
  1224. /* ---------------- Serialization Support -------------- */
  1225. /**
  1226. * Save the state of the <tt>ConcurrentHashMap</tt>
  1227. * instance to a stream (i.e.,
  1228. * serialize it).
  1229. * @param s the stream
  1230. * @serialData
  1231. * the key (Object) and value (Object)
  1232. * for each key-value mapping, followed by a null pair.
  1233. * The key-value mappings are emitted in no particular order.
  1234. */
  1235. private void writeObject(java.io.ObjectOutputStream s) throws IOException {
  1236. s.defaultWriteObject();
  1237. for (int k = 0; k < segments.length; ++k) {
  1238. Segment<K,V> seg = (Segment<K,V>)segments[k];
  1239. seg.lock();
  1240. try {
  1241. HashEntry[] tab = seg.table;
  1242. for (int i = 0; i < tab.length; ++i) {
  1243. for (HashEntry<K,V> e = (HashEntry<K,V>)tab[i]; e != null; e = e.next) {
  1244. s.writeObject(e.key);
  1245. s.writeObject(e.value);
  1246. }
  1247. }
  1248. } finally {
  1249. seg.unlock();
  1250. }
  1251. }
  1252. s.writeObject(null);
  1253. s.writeObject(null);
  1254. }
  1255. /**
  1256. * Reconstitute the <tt>ConcurrentHashMap</tt>
  1257. * instance from a stream (i.e.,
  1258. * deserialize it).
  1259. * @param s the stream
  1260. */
  1261. private void readObject(java.io.ObjectInputStream s)
  1262. throws IOException, ClassNotFoundException {
  1263. s.defaultReadObject();
  1264. // Initialize each segment to be minimally sized, and let grow.
  1265. for (int i = 0; i < segments.length; ++i) {
  1266. segments[i].setTable(new HashEntry[1]);
  1267. }
  1268. // Read the keys and values, and put the mappings in the table
  1269. for (;;) {
  1270. K key = (K) s.readObject();
  1271. V value = (V) s.readObject();
  1272. if (key == null)
  1273. break;
  1274. put(key, value);
  1275. }
  1276. }
  1277. }