@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);
        }
    }
@ SuppressWarnings ( "unchecked" ) private void readObject ( java . io . ObjectInputStream s ) throws IOException , ClassNotFoundException { 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 ) ; UNSAFE . putIntVolatile ( this , HASHSEED_OFFSET , randomHashSeed ( this ) ) ; 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 ] ; } } for ( ; ; ) { K key = ( K ) s . readObject ( ) ; V value = ( V ) s . readObject ( ) ; if ( key == null ) { break ; } put ( key , value ) ; } }
Reconstitute the <tt>ConcurrentHashMap</tt> instance from a
stream (i.e., deserialize it).
@param s the stream