ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentHashMap.java
Revision: 1.8
Committed: Tue Jun 24 14:34:47 2003 UTC (20 years, 11 months ago) by dl
Branch: MAIN
Changes since 1.7: +35 -25 lines
Log Message:
Added missing javadoc tags; minor reformatting

File Contents

# User Rev Content
1 dl 1.2 /*
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 tim 1.1 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 dl 1.4 * A hash table supporting full concurrency of retrievals and
17     * adjustable expected concurrency for updates. This class obeys the
18     * same functional specification as
19     * <tt>java.util.Hashtable</tt>. However, even though all operations
20     * are thread-safe, retrieval operations do <em>not</em> entail
21     * locking, and there is <em>not</em> any support for locking the
22     * entire table in a way that prevents all access. This class is
23     * fully interoperable with Hashtable in programs that rely on its
24     * thread safety but not on its synchronization details.
25     *
26     * <p> Retrieval operations (including <tt>get</tt>) ordinarily
27 dl 1.5 * overlap with update operations (including <tt>put</tt> and
28 dl 1.4 * <tt>remove</tt>). Retrievals reflect the results of the most
29     * recently <em>completed</em> update operations holding upon their
30     * onset. For aggregate operations such as <tt>putAll</tt> and
31     * <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 ConcurrentModificationException.
36     * However, Iterators are designed to be used by only one thread at a
37     * time.
38 tim 1.1 *
39 dl 1.4 * <p> The allowed concurrency among update operations is controlled
40     * by the optional <tt>segments</tt> constructor argument (default
41 brian 1.7 * 16). The table is divided into this many independent parts, each of
42 dl 1.4 * which can be updated concurrently. Because placement in hash tables
43     * is essentially random, the actual concurrency will vary. As a rough
44     * rule of thumb, you should choose at least as many segments as you
45     * expect concurrent threads. However, using more segments than you
46     * need can waste space and time. Using a value of 1 for
47     * <tt>segments</tt> results in a table that is concurrently readable
48     * but can only be updated by one thread at a time.
49 tim 1.1 *
50 dl 1.4 * <p> Like Hashtable but unlike java.util.HashMap, this class does
51     * NOT allow <tt>null</tt> to be used as a key or value.
52 tim 1.1 *
53 dl 1.8 * @since 1.5
54     * @author Doug Lea
55     */
56 tim 1.1 public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
57     implements ConcurrentMap<K, V>, Cloneable, Serializable {
58    
59     /*
60 dl 1.4 * The basic strategy is to subdivide the table among Segments,
61     * each of which itself is a concurrently readable hash table.
62     */
63 tim 1.1
64 dl 1.4 /* ---------------- Constants -------------- */
65    
66     /**
67     * The default initial number of table slots for this table (32).
68     * Used when not otherwise specified in constructor.
69     */
70 dl 1.8 private static int DEFAULT_INITIAL_CAPACITY = 16;
71 tim 1.1
72     /**
73 dl 1.4 * The maximum capacity, used if a higher value is implicitly
74     * specified by either of the constructors with arguments. MUST
75     * be a power of two <= 1<<30.
76     */
77     static final int MAXIMUM_CAPACITY = 1 << 30;
78    
79 tim 1.1 /**
80 dl 1.4 * The default load factor for this table. Used when not
81     * otherwise specified in constructor.
82     */
83     static final float DEFAULT_LOAD_FACTOR = 0.75f;
84 tim 1.1
85     /**
86 dl 1.4 * The default number of concurrency control segments.
87 tim 1.1 **/
88 dl 1.4 private static final int DEFAULT_SEGMENTS = 16;
89 tim 1.1
90 dl 1.4 /* ---------------- Fields -------------- */
91 tim 1.1
92     /**
93 dl 1.4 * Mask value for indexing into segments. The lower bits of a
94     * key's hash code are used to choose the segment, and the
95     * remaining bits are used as the placement hashcode used within
96     * the segment.
97 tim 1.1 **/
98 dl 1.4 private final int segmentMask;
99 tim 1.1
100     /**
101 dl 1.4 * Shift value for indexing within segments.
102 tim 1.1 **/
103 dl 1.4 private final int segmentShift;
104 tim 1.1
105     /**
106 dl 1.4 * The segments, each of which is a specialized hash table
107 tim 1.1 */
108 dl 1.4 private final Segment<K,V>[] segments;
109    
110 dl 1.6 private transient Set<K> keySet;
111     private transient Set/*<Map.Entry<K,V>>*/ entrySet;
112     private transient Collection<V> values;
113 dl 1.4
114     /* ---------------- Small Utilities -------------- */
115 tim 1.1
116     /**
117 dl 1.4 * Return a hash code for non-null Object x.
118     * Uses the same hash code spreader as most other j.u hash tables.
119 dl 1.8 * @param x the object serving as a key
120     * @return the hash code
121 tim 1.1 */
122 dl 1.4 private static int hash(Object x) {
123     int h = x.hashCode();
124     h += ~(h << 9);
125     h ^= (h >>> 14);
126     h += (h << 4);
127     h ^= (h >>> 10);
128     return h;
129     }
130    
131     /**
132     * Check for equality of non-null references x and y.
133     **/
134     private static boolean eq(Object x, Object y) {
135     return x == y || x.equals(y);
136     }
137 tim 1.1
138     /**
139 dl 1.4 * Return index for hash code h in table of given length.
140     */
141     private static int indexFor(int h, int length) {
142     return h & (length-1);
143     }
144 tim 1.1
145     /**
146 dl 1.4 * Return the segment that should be used for key with given hash
147 tim 1.1 */
148 dl 1.4 private Segment<K,V> segmentFor(int hash) {
149     return segments[hash & segmentMask];
150     }
151 tim 1.1
152     /**
153 dl 1.4 * Strip the segment index from hash code to use as a per-segment hash.
154 tim 1.1 */
155 dl 1.4 private int segmentHashFor(int hash) {
156     return hash >>> segmentShift;
157     }
158 tim 1.1
159 dl 1.4 /* ---------------- Inner Classes -------------- */
160 tim 1.1
161     /**
162 dl 1.6 * Segments are specialized versions of hash tables. This
163 dl 1.4 * subclasses from ReentrantLock opportunistically, just to
164     * simplify some locking and avoid separate construction.
165 tim 1.1 **/
166 dl 1.8 private static final class Segment<K,V> extends ReentrantLock implements Serializable {
167 dl 1.4 /*
168     * Segments maintain a table of entry lists that are ALWAYS
169     * kept in a consistent state, so can be read without locking.
170     * Next fields of nodes are immutable (final). All list
171     * additions are performed at the front of each bin. This
172     * makes it easy to check changes, and also fast to traverse.
173     * When nodes would otherwise be changed, new nodes are
174     * created to replace them. This works well for hash tables
175     * since the bin lists tend to be short. (The average length
176     * is less than two for the default load factor threshold.)
177     *
178     * Read operations can thus proceed without locking, but rely
179     * on a memory barrier to ensure that completed write
180     * operations performed by other threads are
181     * noticed. Conveniently, the "count" field, tracking the
182     * number of elements, can also serve as the volatile variable
183     * providing proper read/write barriers. This is convenient
184     * because this field needs to be read in many read operations
185     * anyway. The use of volatiles for this purpose is only
186     * guaranteed to work in accord with reuirements in
187     * multithreaded environments when run on JVMs conforming to
188     * the clarified JSR133 memory model specification. This true
189     * for hotspot as of release 1.4.
190     *
191     * Implementors note. The basic rules for all this are:
192     *
193     * - All unsynchronized read operations must first read the
194     * "count" field, and should not look at table entries if
195     * it is 0.
196     *
197     * - All synchronized write operations should write to
198     * the "count" field after updating. The operations must not
199     * take any action that could even momentarily cause
200     * a concurrent read operation to see inconsistent
201     * data. This is made easier by the nature of the read
202     * operations in Map. For example, no operation
203     * can reveal that the table has grown but the threshold
204     * has not yet been updated, so there are no atomicity
205     * requirements for this with respect to reads.
206     *
207     * As a guide, all critical volatile reads and writes are marked
208     * in code comments.
209     */
210    
211     /**
212     * The number of elements in this segment's region.
213     **/
214     transient volatile int count;
215    
216     /**
217     * The table is rehashed when its size exceeds this threshold.
218     * (The value of this field is always (int)(capacity *
219     * loadFactor).)
220     */
221 dl 1.8 private transient int threshold;
222 dl 1.4
223     /**
224     * The per-segment table
225     */
226     transient HashEntry<K,V>[] table;
227    
228     /**
229     * The load factor for the hash table. Even though this value
230     * is same for all segments, it is replicated to avoid needing
231     * links to outer object.
232     * @serial
233     */
234     private final float loadFactor;
235 tim 1.1
236 dl 1.4 Segment(int initialCapacity, float lf) {
237     loadFactor = lf;
238     setTable(new HashEntry<K,V>[initialCapacity]);
239     }
240 tim 1.1
241 dl 1.4 /**
242     * Set table to new HashEntry array.
243     * Call only while holding lock or in constructor.
244     **/
245     private void setTable(HashEntry<K,V>[] newTable) {
246     table = newTable;
247     threshold = (int)(newTable.length * loadFactor);
248     count = count; // write-volatile
249     }
250    
251     /* Specialized implementations of map methods */
252    
253     V get(K key, int hash) {
254     if (count != 0) { // read-volatile
255     HashEntry<K,V>[] tab = table;
256     int index = indexFor(hash, tab.length);
257     HashEntry<K,V> e = tab[index];
258     while (e != null) {
259     if (e.hash == hash && eq(key, e.key))
260     return e.value;
261     e = e.next;
262     }
263     }
264     return null;
265     }
266    
267     boolean containsKey(Object key, int hash) {
268     if (count != 0) { // read-volatile
269     HashEntry<K,V>[] tab = table;
270     int index = indexFor(hash, tab.length);
271     HashEntry<K,V> e = tab[index];
272     while (e != null) {
273     if (e.hash == hash && eq(key, e.key))
274     return true;
275     e = e.next;
276     }
277     }
278     return false;
279     }
280    
281     boolean containsValue(Object value) {
282     if (count != 0) { // read-volatile
283     HashEntry<K,V> tab[] = table;
284     int len = tab.length;
285     for (int i = 0 ; i < len; i++)
286     for (HashEntry<K,V> e = tab[i] ; e != null ; e = e.next)
287     if (value.equals(e.value))
288     return true;
289     }
290     return false;
291     }
292    
293     V put(K key, int hash, V value, boolean onlyIfAbsent) {
294     lock();
295     try {
296     HashEntry<K,V>[] tab = table;
297     int index = indexFor(hash, tab.length);
298     HashEntry<K,V> first = tab[index];
299    
300     for (HashEntry<K,V> e = first; e != null; e = e.next) {
301     if (e.hash == hash && eq(key, e.key)) {
302     V oldValue = e.value;
303     if (!onlyIfAbsent)
304     e.value = value;
305     count = count; // write-volatile
306     return oldValue;
307     }
308     }
309    
310     tab[index] = new HashEntry<K,V>(hash, key, value, first);
311     if (++count > threshold) // write-volatile
312     rehash();
313     return null;
314     }
315     finally {
316     unlock();
317     }
318     }
319    
320     private void rehash() {
321     HashEntry<K,V>[] oldTable = table;
322     int oldCapacity = oldTable.length;
323     if (oldCapacity >= MAXIMUM_CAPACITY)
324     return;
325    
326     /*
327     * Reclassify nodes in each list to new Map. Because we are
328     * using power-of-two expansion, the elements from each bin
329     * must either stay at same index, or move with a power of two
330     * offset. We eliminate unnecessary node creation by catching
331     * cases where old nodes can be reused because their next
332     * fields won't change. Statistically, at the default
333     * threshhold, only about one-sixth of them need cloning when
334     * a table doubles. The nodes they replace will be garbage
335     * collectable as soon as they are no longer referenced by any
336     * reader thread that may be in the midst of traversing table
337     * right now.
338     */
339    
340     HashEntry<K,V>[] newTable = new HashEntry<K,V>[oldCapacity << 1];
341     int sizeMask = newTable.length - 1;
342     for (int i = 0; i < oldCapacity ; i++) {
343     // We need to guarantee that any existing reads of old Map can
344     // proceed. So we cannot yet null out each bin.
345     HashEntry<K,V> e = oldTable[i];
346    
347     if (e != null) {
348     HashEntry<K,V> next = e.next;
349     int idx = e.hash & sizeMask;
350    
351     // Single node on list
352     if (next == null)
353     newTable[idx] = e;
354    
355     else {
356     // Reuse trailing consecutive sequence at same slot
357     HashEntry<K,V> lastRun = e;
358     int lastIdx = idx;
359     for (HashEntry<K,V> last = next;
360     last != null;
361     last = last.next) {
362     int k = last.hash & sizeMask;
363     if (k != lastIdx) {
364     lastIdx = k;
365     lastRun = last;
366     }
367     }
368     newTable[lastIdx] = lastRun;
369    
370     // Clone all remaining nodes
371     for (HashEntry<K,V> p = e; p != lastRun; p = p.next) {
372     int k = p.hash & sizeMask;
373 dl 1.8 newTable[k] = new HashEntry<K,V>(p.hash,
374     p.key,
375     p.value,
376     newTable[k]);
377 dl 1.4 }
378     }
379     }
380     }
381     setTable(newTable);
382     }
383 dl 1.6
384     /**
385     * Remove; match on key only if value null, else match both.
386     */
387 dl 1.4 V remove(Object key, int hash, Object value) {
388     lock();
389     try {
390     HashEntry[] tab = table;
391     int index = indexFor(hash, tab.length);
392     HashEntry<K,V> first = tab[index];
393    
394     HashEntry<K,V> e = first;
395     while (true) {
396     if (e == null)
397     return null;
398     if (e.hash == hash && eq(key, e.key))
399     break;
400     e = e.next;
401     }
402    
403     V oldValue = e.value;
404     if (value != null && !value.equals(oldValue))
405     return null;
406    
407     // All entries following removed node can stay in list, but
408     // all preceeding ones need to be cloned.
409     HashEntry<K,V> newFirst = e.next;
410     for (HashEntry<K,V> p = first; p != e; p = p.next)
411 dl 1.8 newFirst = new HashEntry<K,V>(p.hash, p.key,
412     p.value, newFirst);
413 dl 1.4 tab[index] = newFirst;
414    
415     count--; // write-volatile
416     return e.value;
417     }
418     finally {
419     unlock();
420     }
421     }
422    
423     void clear() {
424     lock();
425     try {
426     HashEntry<K,V> tab[] = table;
427     for (int i = 0; i < tab.length ; i++)
428     tab[i] = null;
429     count = 0; // write-volatile
430     }
431     finally {
432     unlock();
433     }
434     }
435 tim 1.1 }
436    
437     /**
438 dl 1.4 * ConcurrentReaderHashMap list entry.
439 tim 1.1 */
440 dl 1.4 private static class HashEntry<K,V> implements Entry<K,V> {
441     private final K key;
442     private V value;
443     private final int hash;
444     private final HashEntry<K,V> next;
445    
446     HashEntry(int hash, K key, V value, HashEntry<K,V> next) {
447     this.value = value;
448     this.hash = hash;
449     this.key = key;
450     this.next = next;
451     }
452    
453     public K getKey() {
454     return key;
455     }
456 tim 1.1
457 dl 1.4 public V getValue() {
458     return value;
459 tim 1.1 }
460    
461 dl 1.4 public V setValue(V newValue) {
462     // We aren't required to, and don't provide any
463     // visibility barriers for setting value.
464     if (newValue == null)
465     throw new NullPointerException();
466     V oldValue = this.value;
467     this.value = newValue;
468     return oldValue;
469     }
470 tim 1.1
471 dl 1.4 public boolean equals(Object o) {
472     if (!(o instanceof Entry))
473     return false;
474     Entry<K,V> e = (Entry)o;
475     return (key.equals(e.getKey()) && value.equals(e.getValue()));
476     }
477    
478     public int hashCode() {
479     return key.hashCode() ^ value.hashCode();
480     }
481 tim 1.1
482 dl 1.4 public String toString() {
483     return key + "=" + value;
484     }
485 tim 1.1 }
486    
487 dl 1.4
488     /* ---------------- Public operations -------------- */
489 tim 1.1
490     /**
491     * Constructs a new, empty map with the specified initial
492     * capacity and the specified load factor.
493     *
494 dl 1.4 * @param initialCapacity the initial capacity. The actual
495     * initial capacity is rounded up to the nearest power of two.
496 tim 1.1 * @param loadFactor the load factor threshold, used to control resizing.
497 dl 1.4 * @param segments the number of concurrently accessible segments. the
498     * actual number of segments is rounded to the next power of two.
499     * @throws IllegalArgumentException if the initial capacity is
500     * negative or the load factor or number of segments are
501     * nonpositive.
502     */
503 dl 1.8 public ConcurrentHashMap(int initialCapacity,
504     float loadFactor, int segments) {
505 dl 1.4 if (!(loadFactor > 0) || initialCapacity < 0 || segments <= 0)
506     throw new IllegalArgumentException();
507    
508     // Find power-of-two sizes best matching arguments
509     int sshift = 0;
510     int ssize = 1;
511     while (ssize < segments) {
512     ++sshift;
513     ssize <<= 1;
514     }
515     segmentShift = sshift;
516 dl 1.8 segmentMask = ssize - 1;
517 dl 1.4 this.segments = new Segment<K,V>[ssize];
518    
519     if (initialCapacity > MAXIMUM_CAPACITY)
520     initialCapacity = MAXIMUM_CAPACITY;
521     int c = initialCapacity / ssize;
522     if (c * ssize < initialCapacity)
523     ++c;
524     int cap = 1;
525     while (cap < c)
526     cap <<= 1;
527    
528     for (int i = 0; i < this.segments.length; ++i)
529     this.segments[i] = new Segment<K,V>(cap, loadFactor);
530 tim 1.1 }
531    
532     /**
533     * Constructs a new, empty map with the specified initial
534 dl 1.4 * capacity, and with default load factor and segments.
535 tim 1.1 *
536 dl 1.4 * @param initialCapacity the initial capacity of the
537     * ConcurrentHashMap.
538     * @throws IllegalArgumentException if the initial capacity of
539     * elements is negative.
540 tim 1.1 */
541     public ConcurrentHashMap(int initialCapacity) {
542 dl 1.4 this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
543 tim 1.1 }
544    
545     /**
546 dl 1.4 * Constructs a new, empty map with a default initial capacity,
547     * load factor, and number of segments
548 tim 1.1 */
549     public ConcurrentHashMap() {
550 dl 1.4 this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
551 tim 1.1 }
552    
553     /**
554     * Constructs a new map with the same mappings as the given map. The
555     * map is created with a capacity of twice the number of mappings in
556 dl 1.4 * the given map or 11 (whichever is greater), and a default load factor.
557 tim 1.1 */
558     public <A extends K, B extends V> ConcurrentHashMap(Map<A,B> t) {
559     this(Math.max((int) (t.size() / DEFAULT_LOAD_FACTOR) + 1,
560 dl 1.4 11),
561     DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
562     putAll(t);
563 tim 1.1 }
564    
565 dl 1.4 // inherit Map javadoc
566 tim 1.1 public int size() {
567     int c = 0;
568     for (int i = 0; i < segments.length; ++i)
569 dl 1.4 c += segments[i].count;
570 tim 1.1 return c;
571     }
572    
573 dl 1.4 // inherit Map javadoc
574 tim 1.1 public boolean isEmpty() {
575     for (int i = 0; i < segments.length; ++i)
576 dl 1.4 if (segments[i].count != 0)
577 tim 1.1 return false;
578     return true;
579     }
580    
581     /**
582     * Returns the value to which the specified key is mapped in this table.
583     *
584     * @param key a key in the table.
585     * @return the value to which the key is mapped in this table;
586     * <code>null</code> if the key is not mapped to any value in
587     * this table.
588 dl 1.8 * @throws NullPointerException if the key is
589 tim 1.1 * <code>null</code>.
590     * @see #put(Object, Object)
591     */
592 dl 1.4 public V get(K key) {
593     int hash = hash(key); // throws NullPointerException if key null
594     return segmentFor(hash).get(key, segmentHashFor(hash));
595 tim 1.1 }
596    
597     /**
598     * Tests if the specified object is a key in this table.
599 dl 1.4 *
600 tim 1.1 * @param key possible key.
601 dl 1.4 * @return <code>true</code> if and only if the specified object
602     * is a key in this table, as determined by the
603 tim 1.1 * <tt>equals</tt> method; <code>false</code> otherwise.
604 dl 1.8 * @throws NullPointerException if the key is
605 tim 1.1 * <code>null</code>.
606     * @see #contains(Object)
607     */
608     public boolean containsKey(Object key) {
609 dl 1.4 int hash = hash(key); // throws NullPointerException if key null
610     return segmentFor(hash).containsKey(key, segmentHashFor(hash));
611 tim 1.1 }
612    
613     /**
614     * Returns <tt>true</tt> if this map maps one or more keys to the
615     * specified value. Note: This method requires a full internal
616     * traversal of the hash table, and so is much slower than
617     * method <tt>containsKey</tt>.
618     *
619     * @param value value whose presence in this map is to be tested.
620     * @return <tt>true</tt> if this map maps one or more keys to the
621 dl 1.4 * specified value.
622 dl 1.8 * @throws NullPointerException if the value is <code>null</code>.
623 tim 1.1 */
624     public boolean containsValue(Object value) {
625 dl 1.4 if (value == null)
626     throw new NullPointerException();
627 tim 1.1
628 dl 1.4 for (int i = 0; i < segments.length; ++i) {
629     if (segments[i].containsValue(value))
630     return true;
631 tim 1.1 }
632     return false;
633     }
634     /**
635     * Tests if some key maps into the specified value in this table.
636     * This operation is more expensive than the <code>containsKey</code>
637     * method.<p>
638     *
639     * Note that this method is identical in functionality to containsValue,
640     * (which is part of the Map interface in the collections framework).
641 dl 1.4 *
642 tim 1.1 * @param value a value to search for.
643     * @return <code>true</code> if and only if some key maps to the
644 dl 1.4 * <code>value</code> argument in this table as
645 tim 1.1 * determined by the <tt>equals</tt> method;
646     * <code>false</code> otherwise.
647 dl 1.8 * @throws NullPointerException if the value is <code>null</code>.
648 tim 1.1 * @see #containsKey(Object)
649     * @see #containsValue(Object)
650 dl 1.8 * @see Map
651 tim 1.1 */
652 dl 1.4 public boolean contains(Object value) {
653 tim 1.1 return containsValue(value);
654     }
655    
656     /**
657 dl 1.4 * Maps the specified <code>key</code> to the specified
658     * <code>value</code> in this table. Neither the key nor the
659     * value can be <code>null</code>. <p>
660     *
661     * The value can be retrieved by calling the <code>get</code> method
662     * with a key that is equal to the original key.
663     *
664     * @param key the table key.
665     * @param value the value.
666     * @return the previous value of the specified key in this table,
667     * or <code>null</code> if it did not have one.
668 dl 1.8 * @throws NullPointerException if the key or value is
669 dl 1.4 * <code>null</code>.
670     * @see Object#equals(Object)
671     * @see #get(Object)
672     */
673     public V put(K key, V value) {
674     if (value == null)
675     throw new NullPointerException();
676     int hash = hash(key);
677     return segmentFor(hash).put(key, segmentHashFor(hash), value, false);
678     }
679    
680     /**
681     * If the specified key is not already associated
682     * with a value, associate it with the given value.
683     * This is equivalent to
684     * <pre>
685     * if (!map.containsKey(key)) map.put(key, value);
686     * return get(key);
687     * </pre>
688     * Except that the action is performed atomically.
689     * @param key key with which the specified value is to be associated.
690     * @param value value to be associated with the specified key.
691     * @return previous value associated with specified key, or <tt>null</tt>
692     * if there was no mapping for key. A <tt>null</tt> return can
693     * also indicate that the map previously associated <tt>null</tt>
694     * with the specified key, if the implementation supports
695     * <tt>null</tt> values.
696     *
697     * @throws NullPointerException this map does not permit <tt>null</tt>
698     * keys or values, and the specified key or value is
699     * <tt>null</tt>.
700     *
701     **/
702     public V putIfAbsent(K key, V value) {
703     if (value == null)
704     throw new NullPointerException();
705     int hash = hash(key);
706     return segmentFor(hash).put(key, segmentHashFor(hash), value, true);
707     }
708    
709    
710     /**
711 tim 1.1 * Copies all of the mappings from the specified map to this one.
712     *
713     * These mappings replace any mappings that this map had for any of the
714     * keys currently in the specified Map.
715     *
716     * @param t Mappings to be stored in this map.
717     */
718 dl 1.4 public <K1 extends K, V1 extends V> void putAll(Map<K1,V1> t) {
719 dl 1.8 Iterator<Map.Entry<K1,V1>> it = t.entrySet().iterator();
720     while (it.hasNext()) {
721     Entry<K,V> e = (Entry) it.next();
722 dl 1.4 put(e.getKey(), e.getValue());
723 tim 1.1 }
724 dl 1.4 }
725    
726     /**
727     * Removes the key (and its corresponding value) from this
728     * table. This method does nothing if the key is not in the table.
729     *
730     * @param key the key that needs to be removed.
731     * @return the value to which the key had been mapped in this table,
732     * or <code>null</code> if the key did not have a mapping.
733 dl 1.8 * @throws NullPointerException if the key is
734 dl 1.4 * <code>null</code>.
735     */
736     public V remove(Object key) {
737     int hash = hash(key);
738     return segmentFor(hash).remove(key, segmentHashFor(hash), null);
739     }
740 tim 1.1
741 dl 1.4 /**
742     * Removes the (key, value) pair from this
743     * table. This method does nothing if the key is not in the table,
744 dl 1.6 * or if the key is associated with a different value.
745 dl 1.4 *
746     * @param key the key that needs to be removed.
747     * @param value the associated value. If the value is null,
748     * it means "any value".
749     * @return the value to which the key had been mapped in this table,
750     * or <code>null</code> if the key did not have a mapping.
751 dl 1.8 * @throws NullPointerException if the key is
752 dl 1.4 * <code>null</code>.
753     */
754     public V remove(Object key, Object value) {
755     int hash = hash(key);
756     return segmentFor(hash).remove(key, segmentHashFor(hash), value);
757 tim 1.1 }
758    
759     /**
760     * Removes all mappings from this map.
761     */
762     public void clear() {
763 dl 1.4 for (int i = 0; i < segments.length; ++i)
764     segments[i].clear();
765 tim 1.1 }
766    
767 dl 1.4
768 tim 1.1 /**
769     * Returns a shallow copy of this
770     * <tt>ConcurrentHashMap</tt> instance: the keys and
771     * values themselves are not cloned.
772     *
773     * @return a shallow copy of this map.
774     */
775     public Object clone() {
776 dl 1.4 // We cannot call super.clone, since it would share final
777     // segments array, and there's no way to reassign finals.
778    
779     float lf = segments[0].loadFactor;
780     int segs = segments.length;
781     int cap = (int)(size() / lf);
782     if (cap < segs) cap = segs;
783     ConcurrentHashMap t = new ConcurrentHashMap(cap, lf, segs);
784     t.putAll(this);
785     return t;
786 tim 1.1 }
787    
788     /**
789     * Returns a set view of the keys contained in this map. The set is
790     * backed by the map, so changes to the map are reflected in the set, and
791     * vice-versa. The set supports element removal, which removes the
792     * corresponding mapping from this map, via the <tt>Iterator.remove</tt>,
793     * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
794     * <tt>clear</tt> operations. It does not support the <tt>add</tt> or
795     * <tt>addAll</tt> operations.
796     *
797     * @return a set view of the keys contained in this map.
798     */
799     public Set<K> keySet() {
800     Set<K> ks = keySet;
801 dl 1.8 return (ks != null) ? ks : (keySet = new KeySet());
802 tim 1.1 }
803    
804    
805     /**
806     * Returns a collection view of the values contained in this map. The
807     * collection is backed by the map, so changes to the map are reflected in
808     * the collection, and vice-versa. The collection supports element
809     * removal, which removes the corresponding mapping from this map, via the
810     * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
811     * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
812     * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
813     *
814     * @return a collection view of the values contained in this map.
815     */
816     public Collection<V> values() {
817     Collection<V> vs = values;
818 dl 1.8 return (vs != null) ? vs : (values = new Values());
819 tim 1.1 }
820    
821    
822     /**
823     * Returns a collection view of the mappings contained in this map. Each
824     * element in the returned collection is a <tt>Map.Entry</tt>. The
825     * collection is backed by the map, so changes to the map are reflected in
826     * the collection, and vice-versa. The collection supports element
827     * removal, which removes the corresponding mapping from the map, via the
828     * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
829     * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
830     * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
831     *
832     * @return a collection view of the mappings contained in this map.
833     */
834     public Set<Map.Entry<K,V>> entrySet() {
835     Set<Map.Entry<K,V>> es = entrySet;
836     return (es != null) ? es : (entrySet = new EntrySet());
837     }
838    
839    
840     /**
841     * Returns an enumeration of the keys in this table.
842     *
843     * @return an enumeration of the keys in this table.
844     * @see Enumeration
845     * @see #elements()
846     * @see #keySet()
847     * @see Map
848     */
849 dl 1.4 public Enumeration<K> keys() {
850 tim 1.1 return new KeyIterator();
851     }
852    
853     /**
854     * Returns an enumeration of the values in this table.
855     * Use the Enumeration methods on the returned object to fetch the elements
856     * sequentially.
857     *
858     * @return an enumeration of the values in this table.
859     * @see java.util.Enumeration
860     * @see #keys()
861     * @see #values()
862     * @see Map
863     */
864 dl 1.4 public Enumeration<V> elements() {
865 tim 1.1 return new ValueIterator();
866     }
867    
868 dl 1.4 /* ---------------- Iterator Support -------------- */
869    
870     private abstract class HashIterator {
871     private int nextSegmentIndex;
872     private int nextTableIndex;
873     private HashEntry<K, V>[] currentTable;
874     private HashEntry<K, V> nextEntry;
875     private HashEntry<K, V> lastReturned;
876 tim 1.1
877     private HashIterator() {
878 dl 1.8 nextSegmentIndex = segments.length - 1;
879 dl 1.4 nextTableIndex = -1;
880     advance();
881 tim 1.1 }
882    
883     public boolean hasMoreElements() { return hasNext(); }
884    
885 dl 1.4 private void advance() {
886     if (nextEntry != null && (nextEntry = nextEntry.next) != null)
887     return;
888    
889     while (nextTableIndex >= 0) {
890     if ( (nextEntry = currentTable[nextTableIndex--]) != null)
891     return;
892     }
893    
894     while (nextSegmentIndex >= 0) {
895     Segment<K,V> seg = segments[nextSegmentIndex--];
896     if (seg.count != 0) {
897     currentTable = seg.table;
898 dl 1.8 for (int j = currentTable.length - 1; j >= 0; --j) {
899 dl 1.4 if ( (nextEntry = currentTable[j]) != null) {
900 dl 1.8 nextTableIndex = j - 1;
901 dl 1.4 return;
902     }
903 tim 1.1 }
904     }
905     }
906     }
907    
908 dl 1.4 public boolean hasNext() { return nextEntry != null; }
909 tim 1.1
910 dl 1.4 HashEntry<K,V> nextEntry() {
911     if (nextEntry == null)
912 tim 1.1 throw new NoSuchElementException();
913 dl 1.4 lastReturned = nextEntry;
914     advance();
915     return lastReturned;
916 tim 1.1 }
917    
918     public void remove() {
919     if (lastReturned == null)
920     throw new IllegalStateException();
921     ConcurrentHashMap.this.remove(lastReturned.key);
922     lastReturned = null;
923     }
924 dl 1.4 }
925    
926     private class KeyIterator extends HashIterator implements Iterator<K>, Enumeration<K> {
927     public K next() { return super.nextEntry().key; }
928     public K nextElement() { return super.nextEntry().key; }
929     }
930    
931     private class ValueIterator extends HashIterator implements Iterator<V>, Enumeration<V> {
932     public V next() { return super.nextEntry().value; }
933     public V nextElement() { return super.nextEntry().value; }
934     }
935 tim 1.1
936 dl 1.4 private class EntryIterator extends HashIterator implements Iterator<Entry<K,V>> {
937     public Map.Entry<K,V> next() { return super.nextEntry(); }
938 tim 1.1 }
939    
940 dl 1.4 private class KeySet extends AbstractSet<K> {
941     public Iterator<K> iterator() {
942     return new KeyIterator();
943     }
944     public int size() {
945     return ConcurrentHashMap.this.size();
946     }
947     public boolean contains(Object o) {
948     return ConcurrentHashMap.this.containsKey(o);
949     }
950     public boolean remove(Object o) {
951     return ConcurrentHashMap.this.remove(o) != null;
952     }
953     public void clear() {
954     ConcurrentHashMap.this.clear();
955     }
956 tim 1.1 }
957    
958 dl 1.4 private class Values extends AbstractCollection<V> {
959     public Iterator<V> iterator() {
960     return new ValueIterator();
961     }
962     public int size() {
963     return ConcurrentHashMap.this.size();
964     }
965     public boolean contains(Object o) {
966     return ConcurrentHashMap.this.containsValue(o);
967     }
968     public void clear() {
969     ConcurrentHashMap.this.clear();
970     }
971 tim 1.1 }
972    
973 dl 1.4 private class EntrySet extends AbstractSet {
974     public Iterator<Map.Entry<K,V>> iterator() {
975     return new EntryIterator();
976     }
977     public boolean contains(Object o) {
978     if (!(o instanceof Map.Entry))
979     return false;
980     Map.Entry<K,V> e = (Map.Entry<K,V>)o;
981     V v = ConcurrentHashMap.this.get(e.getKey());
982     return v != null && v.equals(e.getValue());
983     }
984     public boolean remove(Object o) {
985     if (!(o instanceof Map.Entry))
986     return false;
987     Map.Entry<K,V> e = (Map.Entry<K,V>)o;
988     return ConcurrentHashMap.this.remove(e.getKey(), e.getValue()) != null;
989     }
990     public int size() {
991     return ConcurrentHashMap.this.size();
992     }
993     public void clear() {
994     ConcurrentHashMap.this.clear();
995     }
996 tim 1.1 }
997    
998 dl 1.4 /* ---------------- Serialization Support -------------- */
999    
1000 tim 1.1 /**
1001     * Save the state of the <tt>ConcurrentHashMap</tt>
1002     * instance to a stream (i.e.,
1003     * serialize it).
1004 dl 1.8 * @param s the stream
1005 tim 1.1 * @serialData
1006     * the key (Object) and value (Object)
1007     * for each key-value mapping, followed by a null pair.
1008     * The key-value mappings are emitted in no particular order.
1009     */
1010     private void writeObject(java.io.ObjectOutputStream s) throws IOException {
1011     s.defaultWriteObject();
1012    
1013     for (int k = 0; k < segments.length; ++k) {
1014 dl 1.4 Segment<K,V> seg = segments[k];
1015 dl 1.2 seg.lock();
1016     try {
1017 dl 1.4 HashEntry<K,V>[] tab = seg.table;
1018     for (int i = 0; i < tab.length; ++i) {
1019     for (HashEntry<K,V> e = tab[i]; e != null; e = e.next) {
1020     s.writeObject(e.key);
1021     s.writeObject(e.value);
1022     }
1023     }
1024 dl 1.2 }
1025     finally {
1026     seg.unlock();
1027     }
1028 tim 1.1 }
1029     s.writeObject(null);
1030     s.writeObject(null);
1031     }
1032    
1033     /**
1034     * Reconstitute the <tt>ConcurrentHashMap</tt>
1035     * instance from a stream (i.e.,
1036     * deserialize it).
1037 dl 1.8 * @param s the stream
1038 tim 1.1 */
1039     private void readObject(java.io.ObjectInputStream s)
1040     throws IOException, ClassNotFoundException {
1041     s.defaultReadObject();
1042    
1043 dl 1.4 // Initialize each segment to be minimally sized, and let grow.
1044     for (int i = 0; i < segments.length; ++i) {
1045     segments[i].setTable(new HashEntry<K,V>[1]);
1046     }
1047 tim 1.1
1048     // Read the keys and values, and put the mappings in the table
1049     while (true) {
1050     K key = (K) s.readObject();
1051     V value = (V) s.readObject();
1052     if (key == null)
1053     break;
1054     put(key, value);
1055     }
1056     }
1057     }
1058 dl 1.4