code: @SuppressWarnings("unchecked")
      private void readObject(java.io.ObjectInputStream s)
          throws IOException, ClassNotFoundException {
          // Don't call defaultReadObject()
          ObjectInputStream.GetField oisFields = s.readFields();
          final Segment<K,V>[] oisSegments = (Segment<K,V>[])oisFields.get("segments", null);
  
          final int ssize = oisSegments.length;
          if (ssize < 1 || ssize > MAX_SEGMENTS
              || (ssize & (ssize-1)) != 0 ) {
            throw new java.io.InvalidObjectException("Bad number of segments:"
                                                     + ssize);
          }
          int sshift = 0, ssizeTmp = ssize;
          while (ssizeTmp > 1) {
              ++sshift;
              ssizeTmp >>>= 1;
          }
          UNSAFE.putIntVolatile(this, SEGSHIFT_OFFSET, 32 - sshift);
          UNSAFE.putIntVolatile(this, SEGMASK_OFFSET, ssize - 1);
          UNSAFE.putObjectVolatile(this, SEGMENTS_OFFSET, oisSegments);
  
          // set hashMask
          UNSAFE.putIntVolatile(this, HASHSEED_OFFSET, randomHashSeed(this));
  
          // 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 = new HashEntry[cap];
              }
          }
  
          // Read the keys and values, and put the mappings in the table
          for (;;) {
              K key = (K) s.readObject();
              V value = (V) s.readObject();
              if (key == null) {
                break;
              }
              put(key, value);
          }
      }
docs: Reconstitute the <tt>ConcurrentHashMap</tt> instance from a
  stream (i.e., deserialize it).
  @param s the stream