ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentHashMap.java
Revision: 1.2
Committed: Tue May 27 18:14:39 2003 UTC (21 years ago) by dl
Branch: MAIN
Changes since 1.1: +103 -45 lines
Log Message:
re-check-in initial implementations

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain. Use, modify, and
4 * redistribute this code in any way without acknowledgement.
5 */
6
7 package java.util.concurrent;
8
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 /**
16 * A version of Hashtable supporting
17 * concurrency for both retrievals and updates.
18 *
19 * <dl>
20 * <dt> Retrievals
21 *
22 * <dd> Retrievals may overlap updates. Successful retrievals using
23 * get(key) and containsKey(key) usually run without
24 * locking. Unsuccessful retrievals (i.e., when the key is not
25 * present) do involve brief locking. Because
26 * retrieval operations can ordinarily overlap with update operations
27 * (i.e., put, remove, and their derivatives), retrievals can only be
28 * guaranteed to return the results of the most recently
29 * <em>completed</em> operations holding upon their onset. Retrieval
30 * operations may or may not return results reflecting in-progress
31 * writing operations. However, the retrieval operations do always
32 * return consistent results -- either those holding before any single
33 * modification or after it, but never a nonsense result. For
34 * aggregate operations such as putAll and clear, concurrent reads may
35 * reflect insertion or removal of only some entries. <p>
36 *
37 * Iterators and Enumerations (i.e., those returned by
38 * keySet().iterator(), entrySet().iterator(), values().iterator(),
39 * keys(), and elements()) return elements reflecting the state of the
40 * hash table at some point at or since the creation of the
41 * iterator/enumeration. They will return at most one instance of
42 * each element (via next()/nextElement()), but might or might not
43 * reflect puts and removes that have been processed since
44 * construction if the Iterator. They do <em>not</em> throw
45 * ConcurrentModificationException. However, these iterators are
46 * designed to be used by only one thread at a time. Passing an
47 * iterator across multiple threads may lead to unpredictable traversal
48 * if the table is being concurrently modified. <p>
49 *
50 *
51 * <dt> Updates
52 *
53 * <dd> This class supports a hard-wired preset <em>concurrency
54 * level</em> of 32. This allows a maximum of 32 put and/or remove
55 * operations to proceed concurrently. This level is an upper bound on
56 * concurrency, not a guarantee, since it interacts with how
57 * well-strewn elements are across bins of the table. (The preset
58 * value in part reflects the fact that even on large multiprocessors,
59 * factors other than synchronization tend to be bottlenecks when more
60 * than 32 threads concurrently attempt updates.)
61 * Additionally, operations triggering internal resizing and clearing
62 * do not execute concurrently with any operation.
63 * <p>
64 *
65 * There is <em>NOT</em> any support for locking the entire table to
66 * prevent updates.
67 *
68 * </dl>
69 *
70 *
71 * This class may be used as a direct replacement for
72 * java.util.Hashtable in any application that does not rely
73 * on the ability to lock the entire table to prevent updates.
74 * Like Hashtable but unlike java.util.HashMap,
75 * this class does NOT allow <tt>null</tt> to be used as a key or
76 * value.
77 * <p>
78 *
79 **/
80 public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
81 implements ConcurrentMap<K, V>, Cloneable, Serializable {
82
83 /*
84 The basic strategy is an optimistic-style scheme based on
85 the guarantee that the hash table and its lists are always
86 kept in a consistent enough state to be read without locking:
87
88 * Read operations first proceed without locking, by traversing the
89 apparently correct list of the apparently correct bin. If an
90 entry is found, but not invalidated (value field null), it is
91 returned. If not found, operations must recheck (after a memory
92 barrier) to make sure they are using both the right list and
93 the right table (which can change under resizes). If
94 invalidated, reads must acquire main update lock to wait out
95 the update, and then re-traverse.
96
97 * All list additions are at the front of each bin, making it easy
98 to check changes, and also fast to traverse. Entry next
99 pointers are never assigned. Remove() builds new nodes when
100 necessary to preserve this.
101
102 * Remove() (also clear()) invalidates removed nodes to alert read
103 operations that they must wait out the full modifications.
104
105 * Locking for puts, removes (and, when necessary gets, etc)
106 is controlled by Segments, each covering a portion of the
107 table. During operations requiring global exclusivity (mainly
108 resize and clear), ALL of these locks are acquired at once.
109 Note that these segments are NOT contiguous -- they are based
110 on the least 5 bits of hashcodes. This ensures that the same
111 segment controls the same slots before and after resizing, which
112 is necessary for supporting concurrent retrievals. This
113 comes at the price of a mismatch of logical vs physical locality,
114 but this seems not to be a performance problem in practice.
115
116 */
117
118 /**
119 * The hash table data.
120 */
121 private transient Entry<K,V>[] table;
122
123
124 /**
125 * The number of concurrency control segments.
126 * The value can be at most 32 since ints are used
127 * as bitsets over segments. Emprically, it doesn't
128 * seem to pay to decrease it either, so the value should be at least 32.
129 * In other words, do not redefine this :-)
130 **/
131 private static final int CONCURRENCY_LEVEL = 32;
132
133 /**
134 * Mask value for indexing into segments
135 **/
136 private static final int SEGMENT_MASK = CONCURRENCY_LEVEL - 1;
137
138 /**
139 * Bookkeeping for each concurrency control segment.
140 * Each segment contains a local count of the number of
141 * elements in its region.
142 * However, the main use of a Segment is for its lock.
143 **/
144 private final static class Segment extends ReentrantLock {
145 /**
146 * The number of elements in this segment's region.
147 **/
148 private int count;
149
150 /**
151 * Get the count under synch.
152 **/
153 private int getCount() {
154 lock();
155 try {
156 return count;
157 }
158 finally {
159 unlock();
160 }
161 }
162
163 }
164
165 /**
166 * The array of concurrency control segments.
167 **/
168 private transient final Segment[] segments = new Segment[CONCURRENCY_LEVEL];
169
170
171 /**
172 * The default initial number of table slots for this table (32).
173 * Used when not otherwise specified in constructor.
174 **/
175 public static int DEFAULT_INITIAL_CAPACITY = 32;
176
177
178 /**
179 * The minimum capacity, used if a lower value is implicitly specified
180 * by either of the constructors with arguments.
181 * MUST be a power of two.
182 */
183 private static final int MINIMUM_CAPACITY = 32;
184
185 /**
186 * The maximum capacity, used if a higher value is implicitly specified
187 * by either of the constructors with arguments.
188 * MUST be a power of two <= 1<<30.
189 */
190 private static final int MAXIMUM_CAPACITY = 1 << 30;
191
192 /**
193 * The default load factor for this table (0.75)
194 * Used when not otherwise specified in constructor.
195 **/
196 public static final float DEFAULT_LOAD_FACTOR = 0.75f;
197
198 /**
199 * The load factor for the hash table.
200 *
201 * @serial
202 */
203 private final float loadFactor;
204
205 /**
206 * Per-segment resize threshold.
207 *
208 * @serial
209 */
210 private int threshold;
211
212
213 /**
214 * Number of segments voting for resize. The table is
215 * doubled when 1/4 of the segments reach threshold.
216 * Volatile but updated without synch since this is just a heuristic.
217 **/
218 private transient volatile int votesForResize;
219
220
221 /**
222 * Return the number of set bits in w.
223 * For a derivation of this algorithm, see
224 * "Algorithms and data structures with applications to
225 * graphics and geometry", by Jurg Nievergelt and Klaus Hinrichs,
226 * Prentice Hall, 1993.
227 * See also notes by Torsten Sillke at
228 * http://www.mathematik.uni-bielefeld.de/~sillke/PROBLEMS/bitcount
229 **/
230 private static int bitcount(int w) {
231 w -= (0xaaaaaaaa & w) >>> 1;
232 w = (w & 0x33333333) + ((w >>> 2) & 0x33333333);
233 w = (w + (w >>> 4)) & 0x0f0f0f0f;
234 w += w >>> 8;
235 w += w >>> 16;
236 return w & 0xff;
237 }
238
239 /**
240 * Returns the appropriate capacity (power of two) for the specified
241 * initial capacity argument.
242 */
243 private int p2capacity(int initialCapacity) {
244 int cap = initialCapacity;
245
246 // Compute the appropriate capacity
247 int result;
248 if (cap > MAXIMUM_CAPACITY || cap < 0) {
249 result = MAXIMUM_CAPACITY;
250 } else {
251 result = MINIMUM_CAPACITY;
252 while (result < cap)
253 result <<= 1;
254 }
255 return result;
256 }
257
258 /**
259 * Return hash code for Object x. Since we are using power-of-two
260 * tables, it is worth the effort to improve hashcode via
261 * the same multiplicative scheme as used in IdentityHashMap.
262 */
263 private static int hash(Object x) {
264 int h = x.hashCode();
265 // Multiply by 127 (quickly, via shifts), and mix in some high
266 // bits to help guard against bunching of codes that are
267 // consecutive or equally spaced.
268 return ((h << 7) - h + (h >>> 9) + (h >>> 17));
269 }
270
271
272 /**
273 * Check for equality of non-null references x and y.
274 **/
275 private boolean eq(Object x, Object y) {
276 return x == y || x.equals(y);
277 }
278
279 /** Create table array and set the per-segment threshold **/
280 private Entry<K,V>[] newTable(int capacity) {
281 threshold = (int)(capacity * loadFactor / CONCURRENCY_LEVEL) + 1;
282 return new Entry<K,V>[capacity];
283 }
284
285 /**
286 * Constructs a new, empty map with the specified initial
287 * capacity and the specified load factor.
288 *
289 * @param initialCapacity the initial capacity.
290 * The actual initial capacity is rounded up to the nearest power of two.
291 * @param loadFactor the load factor threshold, used to control resizing.
292 * This value is used in an approximate way: When at least
293 * a quarter of the segments of the table reach per-segment threshold, or
294 * one of the segments itself exceeds overall threshold,
295 * the table is doubled.
296 * This will on average cause resizing when the table-wide
297 * load factor is slightly less than the threshold. If you'd like
298 * to avoid resizing, you can set this to a ridiculously large
299 * value.
300 * @throws IllegalArgumentException if the load factor is nonpositive.
301 */
302 public ConcurrentHashMap(int initialCapacity, float loadFactor) {
303 if (!(loadFactor > 0))
304 throw new IllegalArgumentException("Illegal Load factor: "+ loadFactor);
305 this.loadFactor = loadFactor;
306 for (int i = 0; i < segments.length; ++i)
307 segments[i] = new Segment();
308 int cap = p2capacity(initialCapacity);
309 table = newTable(cap);
310 }
311
312 /**
313 * Constructs a new, empty map with the specified initial
314 * capacity and default load factor.
315 *
316 * @param initialCapacity the initial capacity of the
317 * ConcurrentHashMap.
318 * @throws IllegalArgumentException if the initial maximum number
319 * of elements is less
320 * than zero.
321 */
322 public ConcurrentHashMap(int initialCapacity) {
323 this(initialCapacity, DEFAULT_LOAD_FACTOR);
324 }
325
326 /**
327 * Constructs a new, empty map with a default initial capacity
328 * and default load factor.
329 */
330 public ConcurrentHashMap() {
331 this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
332 }
333
334 /**
335 * Constructs a new map with the same mappings as the given map. The
336 * map is created with a capacity of twice the number of mappings in
337 * the given map or 32 (whichever is greater), and a default load factor.
338 */
339 public <A extends K, B extends V> ConcurrentHashMap(Map<A,B> t) {
340 this(Math.max((int) (t.size() / DEFAULT_LOAD_FACTOR) + 1,
341 MINIMUM_CAPACITY),
342 DEFAULT_LOAD_FACTOR);
343 putAll(t);
344 }
345
346 /**
347 * Returns the number of key-value mappings in this map.
348 *
349 * @return the number of key-value mappings in this map.
350 */
351 public int size() {
352 int c = 0;
353 for (int i = 0; i < segments.length; ++i)
354 c += segments[i].getCount();
355 return c;
356 }
357
358 /**
359 * Returns <tt>true</tt> if this map contains no key-value mappings.
360 *
361 * @return <tt>true</tt> if this map contains no key-value mappings.
362 */
363 public boolean isEmpty() {
364 for (int i = 0; i < segments.length; ++i)
365 if (segments[i].getCount() != 0)
366 return false;
367 return true;
368 }
369
370
371 /**
372 * Returns the value to which the specified key is mapped in this table.
373 *
374 * @param key a key in the table.
375 * @return the value to which the key is mapped in this table;
376 * <code>null</code> if the key is not mapped to any value in
377 * this table.
378 * @exception NullPointerException if the key is
379 * <code>null</code>.
380 * @see #put(Object, Object)
381 */
382 public V get(Object key) {
383 int hash = hash(key); // throws null pointer exception if key null
384
385 // Try first without locking...
386 Entry<K,V>[] tab = table;
387 int index = hash & (tab.length - 1);
388 Entry<K,V> first = tab[index];
389 Entry<K,V> e;
390
391 for (e = first; e != null; e = e.next) {
392 if (e.hash == hash && eq(key, e.key)) {
393 V value = e.value;
394 if (value != null)
395 return value;
396 else
397 break;
398 }
399 }
400
401 // Recheck under synch if key apparently not there or interference
402 Segment seg = segments[hash & SEGMENT_MASK];
403 seg.lock();
404 try {
405 tab = table;
406 index = hash & (tab.length - 1);
407 Entry<K,V> newFirst = tab[index];
408 if (e != null || first != newFirst) {
409 for (e = newFirst; e != null; e = e.next) {
410 if (e.hash == hash && eq(key, e.key))
411 return e.value;
412 }
413 }
414 return null;
415 }
416 finally {
417 seg.unlock();
418 }
419 }
420
421 /**
422 * Tests if the specified object is a key in this table.
423 *
424 * @param key possible key.
425 * @return <code>true</code> if and only if the specified object
426 * is a key in this table, as determined by the
427 * <tt>equals</tt> method; <code>false</code> otherwise.
428 * @exception NullPointerException if the key is
429 * <code>null</code>.
430 * @see #contains(Object)
431 */
432 public boolean containsKey(Object key) {
433 return get(key) != null;
434 }
435
436
437 /**
438 * Maps the specified <code>key</code> to the specified
439 * <code>value</code> in this table. Neither the key nor the
440 * value can be <code>null</code>. (Note that this policy is
441 * the same as for java.util.Hashtable, but unlike java.util.HashMap,
442 * which does accept nulls as valid keys and values.)<p>
443 *
444 * The value can be retrieved by calling the <code>get</code> method
445 * with a key that is equal to the original key.
446 *
447 * @param key the table key.
448 * @param value the value.
449 * @return the previous value of the specified key in this table,
450 * or <code>null</code> if it did not have one.
451 * @exception NullPointerException if the key or value is
452 * <code>null</code>.
453 * @see Object#equals(Object)
454 * @see #get(Object)
455 */
456 public V put(K key, V value) {
457 if (value == null)
458 throw new NullPointerException();
459
460 int hash = hash(key);
461 Segment seg = segments[hash & SEGMENT_MASK];
462 int segcount;
463 Entry<K,V>[] tab;
464 int votes;
465
466 seg.lock();
467 try {
468 tab = table;
469 int index = hash & (tab.length-1);
470 Entry<K,V> first = tab[index];
471
472 for (Entry<K,V> e = first; e != null; e = e.next) {
473 if (e.hash == hash && eq(key, e.key)) {
474 V oldValue = e.value;
475 e.value = value;
476 return oldValue;
477 }
478 }
479
480 // Add to front of list
481 Entry<K,V> newEntry = new Entry<K,V>(hash, key, value, first);
482 tab[index] = newEntry;
483
484 if ((segcount = ++seg.count) < threshold)
485 return null;
486
487 int bit = (1 << (hash & SEGMENT_MASK));
488 votes = votesForResize;
489 if ((votes & bit) == 0)
490 votes = votesForResize |= bit;
491 }
492 finally {
493 seg.unlock();
494 }
495
496 // Attempt resize if 1/4 segs vote,
497 // or if this seg itself reaches the overall threshold.
498 // (The latter check is just a safeguard to avoid pathological cases.)
499 if (bitcount(votes) >= CONCURRENCY_LEVEL / 4 ||
500 segcount > (threshold * CONCURRENCY_LEVEL))
501 resize(tab);
502
503 return null;
504 }
505
506 public V putIfAbsent(K key, V value) {
507 if (value == null)
508 throw new NullPointerException();
509
510 int hash = hash(key);
511 Segment seg = segments[hash & SEGMENT_MASK];
512 int segcount;
513 Entry<K,V>[] tab;
514 int votes;
515
516 seg.lock();
517 try {
518 tab = table;
519 int index = hash & (tab.length-1);
520 Entry<K,V> first = tab[index];
521
522 for (Entry<K,V> e = first; e != null; e = e.next) {
523 if (e.hash == hash && eq(key, e.key)) {
524 V oldValue = e.value;
525 return oldValue;
526 }
527 }
528
529 // Add to front of list
530 Entry<K,V> newEntry = new Entry<K,V>(hash, key, value, first);
531 tab[index] = newEntry;
532
533 if ((segcount = ++seg.count) < threshold)
534 return null;
535
536 int bit = (1 << (hash & SEGMENT_MASK));
537 votes = votesForResize;
538 if ((votes & bit) == 0)
539 votes = votesForResize |= bit;
540 }
541 finally {
542 seg.unlock();
543 }
544
545 // Attempt resize if 1/4 segs vote,
546 // or if this seg itself reaches the overall threshold.
547 // (The latter check is just a safeguard to avoid pathological cases.)
548 if (bitcount(votes) >= CONCURRENCY_LEVEL / 4 ||
549 segcount > (threshold * CONCURRENCY_LEVEL))
550 resize(tab);
551
552 return value;
553 }
554
555 /**
556 * Gather all locks in order to call rehash, by
557 * recursing within synch blocks for each segment index.
558 * @param index the current segment. initially call value must be 0
559 * @param assumedTab the state of table on first call to resize. If
560 * this changes on any call, the attempt is aborted because the
561 * table has already been resized by another thread.
562 */
563 private void resize(Entry<K,V>[] assumedTab) {
564 boolean ok = true;
565 int lastlocked = 0;
566 for (int i = 0; i < segments.length; ++i) {
567 segments[i].lock();
568 lastlocked = i;
569 if (table != assumedTab) {
570 ok = false;
571 break;
572 }
573 }
574 try {
575 if (ok)
576 rehash();
577 }
578 finally {
579 for (int i = lastlocked; i >= 0; --i)
580 segments[i].unlock();
581 }
582 }
583
584 /**
585 * Rehashes the contents of this map into a new table
586 * with a larger capacity.
587 */
588 private void rehash() {
589 votesForResize = 0; // reset
590
591 Entry<K,V>[] oldTable = table;
592 int oldCapacity = oldTable.length;
593
594 if (oldCapacity >= MAXIMUM_CAPACITY) {
595 threshold = Integer.MAX_VALUE; // avoid retriggering
596 return;
597 }
598
599 int newCapacity = oldCapacity << 1;
600 Entry<K,V>[] newTable = newTable(newCapacity);
601 int mask = newCapacity - 1;
602
603 /*
604 * Reclassify nodes in each list to new Map. Because we are
605 * using power-of-two expansion, the elements from each bin
606 * must either stay at same index, or move to
607 * oldCapacity+index. We also eliminate unnecessary node
608 * creation by catching cases where old nodes can be reused
609 * because their next fields won't change. Statistically, at
610 * the default threshhold, only about one-sixth of them need
611 * cloning. (The nodes they replace will be garbage
612 * collectable as soon as they are no longer referenced by any
613 * reader thread that may be in the midst of traversing table
614 * right now.)
615 */
616
617 for (int i = 0; i < oldCapacity ; i++) {
618 // We need to guarantee that any existing reads of old Map can
619 // proceed. So we cannot yet null out each bin.
620 Entry<K,V> e = oldTable[i];
621
622 if (e != null) {
623 int idx = e.hash & mask;
624 Entry<K,V> next = e.next;
625
626 // Single node on list
627 if (next == null)
628 newTable[idx] = e;
629
630 else {
631 // Reuse trailing consecutive sequence of all same bit
632 Entry<K,V> lastRun = e;
633 int lastIdx = idx;
634 for (Entry<K,V> last = next; last != null; last = last.next) {
635 int k = last.hash & mask;
636 if (k != lastIdx) {
637 lastIdx = k;
638 lastRun = last;
639 }
640 }
641 newTable[lastIdx] = lastRun;
642
643 // Clone all remaining nodes
644 for (Entry<K,V> p = e; p != lastRun; p = p.next) {
645 int k = p.hash & mask;
646 newTable[k] = new Entry<K,V>(p.hash, p.key,
647 p.value, newTable[k]);
648 }
649 }
650 }
651 }
652
653 table = newTable;
654 }
655
656
657 /**
658 * Removes the key (and its corresponding value) from this
659 * table. This method does nothing if the key is not in the table.
660 *
661 * @param key the key that needs to be removed.
662 * @return the value to which the key had been mapped in this table,
663 * or <code>null</code> if the key did not have a mapping.
664 * @exception NullPointerException if the key is
665 * <code>null</code>.
666 */
667 public V remove(Object key) {
668 return remove(key, null);
669 }
670
671
672 /**
673 * Removes the (key, value) pair from this
674 * table. This method does nothing if the key is not in the table,
675 * or if the key is associated with a different value. This method
676 * is needed by EntrySet.
677 *
678 * @param key the key that needs to be removed.
679 * @param value the associated value. If the value is null,
680 * it means "any value".
681 * @return the value to which the key had been mapped in this table,
682 * or <code>null</code> if the key did not have a mapping.
683 * @exception NullPointerException if the key is
684 * <code>null</code>.
685 */
686 private V remove(Object key, V value) {
687 /*
688 Find the entry, then
689 1. Set value field to null, to force get() to retry
690 2. Rebuild the list without this entry.
691 All entries following removed node can stay in list, but
692 all preceeding ones need to be cloned. Traversals rely
693 on this strategy to ensure that elements will not be
694 repeated during iteration.
695 */
696
697 int hash = hash(key);
698 Segment seg = segments[hash & SEGMENT_MASK];
699
700 seg.lock();
701 try {
702 Entry<K,V>[] tab = table;
703 int index = hash & (tab.length-1);
704 Entry<K,V> first = tab[index];
705 Entry<K,V> e = first;
706
707 for (;;) {
708 if (e == null)
709 return null;
710 if (e.hash == hash && eq(key, e.key))
711 break;
712 e = e.next;
713 }
714
715 V oldValue = e.value;
716 if (value != null && !value.equals(oldValue))
717 return null;
718
719 e.value = null;
720
721 Entry<K,V> head = e.next;
722 for (Entry<K,V> p = first; p != e; p = p.next)
723 head = new Entry<K,V>(p.hash, p.key, p.value, head);
724 tab[index] = head;
725 seg.count--;
726 return oldValue;
727 }
728 finally {
729 seg.unlock();
730 }
731 }
732
733
734 /**
735 * Returns <tt>true</tt> if this map maps one or more keys to the
736 * specified value. Note: This method requires a full internal
737 * traversal of the hash table, and so is much slower than
738 * method <tt>containsKey</tt>.
739 *
740 * @param value value whose presence in this map is to be tested.
741 * @return <tt>true</tt> if this map maps one or more keys to the
742 * specified value.
743 * @exception NullPointerException if the value is <code>null</code>.
744 */
745 public boolean containsValue(Object value) {
746
747 if (value == null) throw new NullPointerException();
748
749 for (int s = 0; s < segments.length; ++s) {
750 Segment seg = segments[s];
751 Entry<K,V>[] tab;
752 seg.lock();
753 try {
754 tab = table;
755 }
756 finally {
757 seg.unlock();
758 }
759 for (int i = s; i < tab.length; i+= segments.length) {
760 for (Entry<K,V> e = tab[i]; e != null; e = e.next)
761 if (value.equals(e.value))
762 return true;
763 }
764 }
765 return false;
766 }
767
768 /**
769 * Tests if some key maps into the specified value in this table.
770 * This operation is more expensive than the <code>containsKey</code>
771 * method.<p>
772 *
773 * Note that this method is identical in functionality to containsValue,
774 * (which is part of the Map interface in the collections framework).
775 *
776 * @param value a value to search for.
777 * @return <code>true</code> if and only if some key maps to the
778 * <code>value</code> argument in this table as
779 * determined by the <tt>equals</tt> method;
780 * <code>false</code> otherwise.
781 * @exception NullPointerException if the value is <code>null</code>.
782 * @see #containsKey(Object)
783 * @see #containsValue(Object)
784 * @see Map
785 */
786 public boolean contains(V value) {
787 return containsValue(value);
788 }
789
790 /**
791 * Copies all of the mappings from the specified map to this one.
792 *
793 * These mappings replace any mappings that this map had for any of the
794 * keys currently in the specified Map.
795 *
796 * @param t Mappings to be stored in this map.
797 */
798 public <A extends K, B extends V> void putAll(Map<A, B> t) {
799 int n = t.size();
800 if (n == 0)
801 return;
802
803 // Expand enough to hold at least n elements without resizing.
804 // We can only resize table by factor of two at a time.
805 // It is faster to rehash with fewer elements, so do it now.
806 for(;;) {
807 Entry<K,V>[] tab;
808 int max;
809 // must synch on some segment. pick 0.
810 segments[0].lock();
811 try {
812 tab = table;
813 max = threshold * CONCURRENCY_LEVEL;
814 }
815 finally {
816 segments[0].unlock();
817 }
818 if (n < max)
819 break;
820 resize(tab);
821 }
822
823 for (Iterator<Map.Entry<A,B>> it = t.entrySet().iterator(); it.hasNext();) {
824 Map.Entry<A,B> entry = (Map.Entry<A,B>) it.next();
825 put(entry.getKey(), entry.getValue());
826 }
827 }
828
829 /**
830 * Removes all mappings from this map.
831 */
832 public void clear() {
833 // We don't need all locks at once so long as locks
834 // are obtained in low to high order
835 for (int s = 0; s < segments.length; ++s) {
836 Segment seg = segments[s];
837 seg.lock();
838 try {
839 Entry<K,V>[] tab = table;
840 for (int i = s; i < tab.length; i+= segments.length) {
841 for (Entry<K,V> e = tab[i]; e != null; e = e.next)
842 e.value = null;
843 tab[i] = null;
844 seg.count = 0;
845 }
846 }
847 finally {
848 seg.unlock();
849 }
850 }
851 }
852
853 /**
854 * Returns a shallow copy of this
855 * <tt>ConcurrentHashMap</tt> instance: the keys and
856 * values themselves are not cloned.
857 *
858 * @return a shallow copy of this map.
859 */
860 public Object clone() {
861 // We cannot call super.clone, since it would share final segments array,
862 // and there's no way to reassign finals.
863 return new ConcurrentHashMap<K,V>(this);
864 }
865
866 // Views
867
868 private transient Set<K> keySet = null;
869 private transient Set<Map.Entry<K,V>> entrySet = null;
870 private transient Collection<V> values = null;
871
872 /**
873 * Returns a set view of the keys contained in this map. The set is
874 * backed by the map, so changes to the map are reflected in the set, and
875 * vice-versa. The set supports element removal, which removes the
876 * corresponding mapping from this map, via the <tt>Iterator.remove</tt>,
877 * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
878 * <tt>clear</tt> operations. It does not support the <tt>add</tt> or
879 * <tt>addAll</tt> operations.
880 *
881 * @return a set view of the keys contained in this map.
882 */
883 public Set<K> keySet() {
884 Set<K> ks = keySet;
885 return (ks != null)? ks : (keySet = new KeySet());
886 }
887
888 private class KeySet extends AbstractSet<K> {
889 public Iterator<K> iterator() {
890 return new KeyIterator();
891 }
892 public int size() {
893 return ConcurrentHashMap.this.size();
894 }
895 public boolean contains(Object o) {
896 return ConcurrentHashMap.this.containsKey(o);
897 }
898 public boolean remove(Object o) {
899 return ConcurrentHashMap.this.remove(o) != null;
900 }
901 public void clear() {
902 ConcurrentHashMap.this.clear();
903 }
904 }
905
906 /**
907 * Returns a collection view of the values contained in this map. The
908 * collection is backed by the map, so changes to the map are reflected in
909 * the collection, and vice-versa. The collection supports element
910 * removal, which removes the corresponding mapping from this map, via the
911 * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
912 * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
913 * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
914 *
915 * @return a collection view of the values contained in this map.
916 */
917 public Collection<V> values() {
918 Collection<V> vs = values;
919 return (vs != null)? vs : (values = new Values());
920 }
921
922 private class Values extends AbstractCollection<V> {
923 public Iterator<V> iterator() {
924 return new ValueIterator();
925 }
926 public int size() {
927 return ConcurrentHashMap.this.size();
928 }
929 public boolean contains(Object o) {
930 return ConcurrentHashMap.this.containsValue(o);
931 }
932 public void clear() {
933 ConcurrentHashMap.this.clear();
934 }
935 }
936
937 /**
938 * Returns a collection view of the mappings contained in this map. Each
939 * element in the returned collection is a <tt>Map.Entry</tt>. The
940 * collection is backed by the map, so changes to the map are reflected in
941 * the collection, and vice-versa. The collection supports element
942 * removal, which removes the corresponding mapping from the map, via the
943 * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
944 * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
945 * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
946 *
947 * @return a collection view of the mappings contained in this map.
948 */
949 public Set<Map.Entry<K,V>> entrySet() {
950 Set<Map.Entry<K,V>> es = entrySet;
951 return (es != null) ? es : (entrySet = new EntrySet());
952 }
953
954 private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
955 public Iterator<Map.Entry<K,V>> iterator() {
956 return new EntryIterator();
957 }
958 public boolean contains(Map.Entry<K,V> entry) {
959 V v = ConcurrentHashMap.this.get(entry.getKey());
960 return v != null && v.equals(entry.getValue());
961 }
962 public boolean remove(Map.Entry<K,V> e) {
963 return ConcurrentHashMap.this.remove(e.getKey(), e.getValue()) != null;
964 }
965 public int size() {
966 return ConcurrentHashMap.this.size();
967 }
968 public void clear() {
969 ConcurrentHashMap.this.clear();
970 }
971 }
972
973 /**
974 * Returns an enumeration of the keys in this table.
975 *
976 * @return an enumeration of the keys in this table.
977 * @see Enumeration
978 * @see #elements()
979 * @see #keySet()
980 * @see Map
981 */
982 public Enumeration keys() {
983 return new KeyIterator();
984 }
985
986 /**
987 * Returns an enumeration of the values in this table.
988 * Use the Enumeration methods on the returned object to fetch the elements
989 * sequentially.
990 *
991 * @return an enumeration of the values in this table.
992 * @see java.util.Enumeration
993 * @see #keys()
994 * @see #values()
995 * @see Map
996 */
997 public Enumeration elements() {
998 return new ValueIterator();
999 }
1000
1001 /**
1002 * ConcurrentHashMap collision list entry.
1003 */
1004 private static class Entry<K,V> implements Map.Entry<K,V> {
1005 /*
1006 The use of volatile for value field ensures that
1007 we can detect status changes without synchronization.
1008 The other fields are never changed, and are
1009 marked as final.
1010 */
1011
1012 private final K key;
1013 private volatile V value;
1014 private final int hash;
1015 private final Entry<K,V> next;
1016
1017 Entry(int hash, K key, V value, Entry<K,V> next) {
1018 this.value = value;
1019 this.hash = hash;
1020 this.key = key;
1021 this.next = next;
1022 }
1023
1024 // Map.Entry Ops
1025
1026 public K getKey() {
1027 return key;
1028 }
1029
1030 /**
1031 * Get the value. Note: In an entrySet or entrySet.iterator,
1032 * unless you can guarantee lack of concurrent modification,
1033 * <tt>getValue</tt> <em>might</em> return null, reflecting the
1034 * fact that the entry has been concurrently removed. However,
1035 * there are no assurances that concurrent removals will be
1036 * reflected using this method.
1037 *
1038 * @return the current value, or null if the entry has been
1039 * detectably removed.
1040 **/
1041 public V getValue() {
1042 return value;
1043 }
1044
1045 /**
1046 * Set the value of this entry. Note: In an entrySet or
1047 * entrySet.iterator), unless you can guarantee lack of concurrent
1048 * modification, <tt>setValue</tt> is not strictly guaranteed to
1049 * actually replace the value field obtained via the <tt>get</tt>
1050 * operation of the underlying hash table in multithreaded
1051 * applications. If iterator-wide synchronization is not used,
1052 * and any other concurrent <tt>put</tt> or <tt>remove</tt>
1053 * operations occur, sometimes even to <em>other</em> entries,
1054 * then this change is not guaranteed to be reflected in the hash
1055 * table. (It might, or it might not. There are no assurances
1056 * either way.)
1057 *
1058 * @param value the new value.
1059 * @return the previous value, or null if entry has been detectably
1060 * removed.
1061 * @exception NullPointerException if the value is <code>null</code>.
1062 *
1063 **/
1064 public V setValue(V value) {
1065 if (value == null)
1066 throw new NullPointerException();
1067 V oldValue = this.value;
1068 this.value = value;
1069 return oldValue;
1070 }
1071
1072 public boolean equals(Object o) {
1073 if (!(o instanceof Map.Entry))
1074 return false;
1075 Map.Entry e = (Map.Entry)o;
1076 return (key.equals(e.getKey()) && value.equals(e.getValue()));
1077 }
1078
1079 public int hashCode() {
1080 return key.hashCode() ^ value.hashCode();
1081 }
1082
1083 public String toString() {
1084 return key + "=" + value;
1085 }
1086
1087 }
1088
1089 private abstract class HashIterator<T> implements Iterator<T>, Enumeration {
1090 private final Entry<K,V>[] tab; // snapshot of table
1091 private int index; // current slot
1092 Entry<K,V> entry = null; // current node of slot
1093 K currentKey; // key for current node
1094 V currentValue; // value for current node
1095 private Entry lastReturned = null; // last node returned by next
1096
1097 private HashIterator() {
1098 // force all segments to synch
1099 for (int i = 0; i < segments.length; ++i) {
1100 segments[i].lock();
1101 segments[i].unlock();
1102 }
1103 tab = table;
1104 index = tab.length - 1;
1105 }
1106
1107 public boolean hasMoreElements() { return hasNext(); }
1108 public Object nextElement() { return next(); }
1109
1110 public boolean hasNext() {
1111 /*
1112 currentkey and currentValue are set here to ensure that next()
1113 returns normally if hasNext() returns true. This avoids
1114 surprises especially when final element is removed during
1115 traversal -- instead, we just ignore the removal during
1116 current traversal.
1117 */
1118
1119 while (true) {
1120 if (entry != null) {
1121 V v = entry.value;
1122 if (v != null) {
1123 currentKey = entry.key;
1124 currentValue = v;
1125 return true;
1126 }
1127 else
1128 entry = entry.next;
1129 }
1130
1131 while (entry == null && index >= 0)
1132 entry = tab[index--];
1133
1134 if (entry == null) {
1135 currentKey = null;
1136 currentValue = null;
1137 return false;
1138 }
1139 }
1140 }
1141
1142 abstract T returnValueOfNext();
1143
1144 public T next() {
1145 if (currentKey == null && !hasNext())
1146 throw new NoSuchElementException();
1147
1148 T result = returnValueOfNext();
1149 lastReturned = entry;
1150 currentKey = null;
1151 currentValue = null;
1152 entry = entry.next;
1153 return result;
1154 }
1155
1156 public void remove() {
1157 if (lastReturned == null)
1158 throw new IllegalStateException();
1159 ConcurrentHashMap.this.remove(lastReturned.key);
1160 lastReturned = null;
1161 }
1162
1163 }
1164
1165 private class KeyIterator extends HashIterator<K> {
1166 K returnValueOfNext() { return currentKey; }
1167 public K next() { return super.next(); }
1168 }
1169
1170 private class ValueIterator extends HashIterator<V> {
1171 V returnValueOfNext() { return currentValue; }
1172 public V next() { return super.next(); }
1173 }
1174
1175 private class EntryIterator extends HashIterator<Map.Entry<K,V>> {
1176 Map.Entry<K,V> returnValueOfNext() { return entry; }
1177 public Map.Entry<K,V> next() { return super.next(); }
1178 }
1179
1180 /**
1181 * Save the state of the <tt>ConcurrentHashMap</tt>
1182 * instance to a stream (i.e.,
1183 * serialize it).
1184 *
1185 * @serialData
1186 * An estimate of the table size, followed by
1187 * the key (Object) and value (Object)
1188 * for each key-value mapping, followed by a null pair.
1189 * The key-value mappings are emitted in no particular order.
1190 */
1191 private void writeObject(java.io.ObjectOutputStream s) throws IOException {
1192 // Write out the loadfactor, and any hidden stuff
1193 s.defaultWriteObject();
1194
1195 // Write out capacity estimate. It is OK if this
1196 // changes during the write, since it is only used by
1197 // readObject to set initial capacity, to avoid needless resizings.
1198
1199 int cap;
1200 segments[0].lock();
1201 try {
1202 cap = table.length;
1203 }
1204 finally {
1205 segments[0].unlock();
1206 }
1207 s.writeInt(cap);
1208
1209 // Write out keys and values (alternating)
1210 for (int k = 0; k < segments.length; ++k) {
1211 Segment seg = segments[k];
1212 Entry[] tab;
1213 seg.lock();
1214 try {
1215 tab = table;
1216 }
1217 finally {
1218 seg.unlock();
1219 }
1220 for (int i = k; i < tab.length; i+= segments.length) {
1221 for (Entry e = tab[i]; e != null; e = e.next) {
1222 s.writeObject(e.key);
1223 s.writeObject(e.value);
1224 }
1225 }
1226 }
1227
1228 s.writeObject(null);
1229 s.writeObject(null);
1230 }
1231
1232 /**
1233 * Reconstitute the <tt>ConcurrentHashMap</tt>
1234 * instance from a stream (i.e.,
1235 * deserialize it).
1236 */
1237 private void readObject(java.io.ObjectInputStream s)
1238 throws IOException, ClassNotFoundException {
1239
1240 // Read in the threshold, loadfactor, and any hidden stuff
1241 s.defaultReadObject();
1242
1243 int cap = s.readInt();
1244 table = newTable(cap);
1245 for (int i = 0; i < segments.length; ++i)
1246 segments[i] = new Segment();
1247
1248
1249 // Read the keys and values, and put the mappings in the table
1250 while (true) {
1251 K key = (K) s.readObject();
1252 V value = (V) s.readObject();
1253 if (key == null)
1254 break;
1255 put(key, value);
1256 }
1257 }
1258 }