src/share/classes/java/util/concurrent/ConcurrentHashMap.java

Print this page

        

@@ -35,13 +35,10 @@
 
 package java.util.concurrent;
 import java.util.concurrent.locks.*;
 import java.util.*;
 import java.io.Serializable;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
 
 /**
  * A hash table supporting full concurrency of retrievals and
  * adjustable expected concurrency for updates. This class obeys the
  * same functional specification as {@link java.util.Hashtable}, and

@@ -226,11 +223,11 @@
         static final sun.misc.Unsafe UNSAFE;
         static final long nextOffset;
         static {
             try {
                 UNSAFE = sun.misc.Unsafe.getUnsafe();
-                Class k = HashEntry.class;
+                Class<?> k = HashEntry.class;
                 nextOffset = UNSAFE.objectFieldOffset
                     (k.getDeclaredField("next"));
             } catch (Exception e) {
                 throw new Error(e);
             }

@@ -431,11 +428,11 @@
             HashEntry<K,V>[] oldTable = table;
             int oldCapacity = oldTable.length;
             int newCapacity = oldCapacity << 1;
             threshold = (int)(newCapacity * loadFactor);
             HashEntry<K,V>[] newTable =
-                (HashEntry<K,V>[]) new HashEntry[newCapacity];
+                (HashEntry<K,V>[]) new HashEntry<?,?>[newCapacity];
             int sizeMask = newCapacity - 1;
             for (int i = 0; i < oldCapacity ; i++) {
                 HashEntry<K,V> e = oldTable[i];
                 if (e != null) {
                     HashEntry<K,V> next = e.next;

@@ -675,11 +672,11 @@
         if ((seg = (Segment<K,V>)UNSAFE.getObjectVolatile(ss, u)) == null) {
             Segment<K,V> proto = ss[0]; // use segment 0 as prototype
             int cap = proto.table.length;
             float lf = proto.loadFactor;
             int threshold = (int)(cap * lf);
-            HashEntry<K,V>[] tab = (HashEntry<K,V>[])new HashEntry[cap];
+            HashEntry<K,V>[] tab = (HashEntry<K,V>[])new HashEntry<?,?>[cap];
             if ((seg = (Segment<K,V>)UNSAFE.getObjectVolatile(ss, u))
                 == null) { // recheck
                 Segment<K,V> s = new Segment<K,V>(lf, threshold, tab);
                 while ((seg = (Segment<K,V>)UNSAFE.getObjectVolatile(ss, u))
                        == null) {

@@ -692,20 +689,20 @@
     }
 
     // Hash-based segment and entry accesses
 
     /**
-     * Get the segment for the given hash
+     * Gets the segment for the given hash code.
      */
     @SuppressWarnings("unchecked")
     private Segment<K,V> segmentForHash(int h) {
         long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE;
         return (Segment<K,V>) UNSAFE.getObjectVolatile(segments, u);
     }
 
     /**
-     * Gets the table entry for the given segment and hash
+     * Gets the table entry for the given segment and hash code.
      */
     @SuppressWarnings("unchecked")
     static final <K,V> HashEntry<K,V> entryForHash(Segment<K,V> seg, int h) {
         HashEntry<K,V>[] tab;
         return (seg == null || (tab = seg.table) == null) ? null :

@@ -756,12 +753,12 @@
         while (cap < c)
             cap <<= 1;
         // create segments and segments[0]
         Segment<K,V> s0 =
             new Segment<K,V>(loadFactor, (int)(cap * loadFactor),
-                             (HashEntry<K,V>[])new HashEntry[cap]);
-        Segment<K,V>[] ss = (Segment<K,V>[])new Segment[ssize];
+                             (HashEntry<K,V>[])new HashEntry<?,?>[cap]);
+        Segment<K,V>[] ss = (Segment<K,V>[])new Segment<?,?>[ssize];
         UNSAFE.putOrderedObject(ss, SBASE, s0); // ordered write of segments[0]
         this.segments = ss;
     }
 
     /**

@@ -914,10 +911,11 @@
      * then this method returns {@code v}; otherwise it returns
      * {@code null}.  (There can be at most one such mapping.)
      *
      * @throws NullPointerException if the specified key is null
      */
+    @SuppressWarnings("unchecked")
     public V get(Object key) {
         Segment<K,V> s; // manually integrate access methods to reduce overhead
         HashEntry<K,V>[] tab;
         int h = hash(key.hashCode());
         long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE;

@@ -1024,11 +1022,11 @@
      * in this table.  This method is identical in functionality to
      * {@link #containsValue}, and exists solely to ensure
      * full compatibility with class {@link java.util.Hashtable},
      * which supported this method prior to introduction of the
      * Java Collections framework.
-
+     *
      * @param  value a value to search for
      * @return <tt>true</tt> if and only if some key maps to the
      *         <tt>value</tt> argument in this table as
      *         determined by the <tt>equals</tt> method;
      *         <tt>false</tt> otherwise

@@ -1260,11 +1258,11 @@
             nextTableIndex = -1;
             advance();
         }
 
         /**
-         * Set nextEntry to first node of next non-empty table
+         * Sets nextEntry to first node of next non-empty table
          * (in backwards order, to simplify checks).
          */
         final void advance() {
             for (;;) {
                 if (nextTableIndex >= 0) {

@@ -1324,16 +1322,18 @@
      * setValue changes to the underlying map.
      */
     final class WriteThroughEntry
         extends AbstractMap.SimpleEntry<K,V>
     {
+        static final long serialVersionUID = 7249069246763182397L;
+
         WriteThroughEntry(K k, V v) {
             super(k,v);
         }
 
         /**
-         * Set our entry's value and write through to the map. The
+         * Sets our entry's value and writes through to the map. The
          * value to return is somewhat arbitrary here. Since a
          * WriteThroughEntry does not necessarily track asynchronous
          * changes, the most recent "previous" value could be
          * different from what we return (or could even have been
          * removed in which case the put will re-establish). We do not

@@ -1425,19 +1425,20 @@
     }
 
     /* ---------------- Serialization Support -------------- */
 
     /**
-     * Save the state of the <tt>ConcurrentHashMap</tt> instance to a
-     * stream (i.e., serialize it).
+     * Saves the state of the <tt>ConcurrentHashMap</tt> instance to a
+     * stream (i.e., serializes it).
      * @param s the stream
      * @serialData
      * the key (Object) and value (Object)
      * for each key-value mapping, followed by a null pair.
      * The key-value mappings are emitted in no particular order.
      */
-    private void writeObject(java.io.ObjectOutputStream s) throws IOException {
+    private void writeObject(java.io.ObjectOutputStream s)
+            throws java.io.IOException {
         // force all segments for serialization compatibility
         for (int k = 0; k < segments.length; ++k)
             ensureSegment(k);
         s.defaultWriteObject();
 

@@ -1461,27 +1462,27 @@
         s.writeObject(null);
         s.writeObject(null);
     }
 
     /**
-     * Reconstitute the <tt>ConcurrentHashMap</tt> instance from a
-     * stream (i.e., deserialize it).
+     * Reconstitutes the <tt>ConcurrentHashMap</tt> instance from a
+     * stream (i.e., deserializes it).
      * @param s the stream
      */
     @SuppressWarnings("unchecked")
     private void readObject(java.io.ObjectInputStream s)
-        throws IOException, ClassNotFoundException {
+            throws java.io.IOException, ClassNotFoundException {
         s.defaultReadObject();
 
         // Re-initialize segments to be minimally sized, and let grow.
         int cap = MIN_SEGMENT_TABLE_CAPACITY;
         final Segment<K,V>[] segments = this.segments;
         for (int k = 0; k < segments.length; ++k) {
             Segment<K,V> seg = segments[k];
             if (seg != null) {
                 seg.threshold = (int)(cap * seg.loadFactor);
-                seg.table = (HashEntry<K,V>[]) new HashEntry[cap];
+                seg.table = (HashEntry<K,V>[]) new HashEntry<?,?>[cap];
             }
         }
 
         // Read the keys and values, and put the mappings in the table
         for (;;) {

@@ -1502,12 +1503,12 @@
 
     static {
         int ss, ts;
         try {
             UNSAFE = sun.misc.Unsafe.getUnsafe();
-            Class tc = HashEntry[].class;
-            Class sc = Segment[].class;
+            Class<?> tc = HashEntry[].class;
+            Class<?> sc = Segment[].class;
             TBASE = UNSAFE.arrayBaseOffset(tc);
             SBASE = UNSAFE.arrayBaseOffset(sc);
             ts = UNSAFE.arrayIndexScale(tc);
             ss = UNSAFE.arrayIndexScale(sc);
         } catch (Exception e) {