--- old/src/share/classes/java/lang/String.java 2012-05-29 16:26:34.000000000 -0700 +++ new/src/share/classes/java/lang/String.java 2012-05-29 16:26:34.000000000 -0700 @@ -25,7 +25,6 @@ package java.lang; -import java.io.ObjectStreamClass; import java.io.ObjectStreamField; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; @@ -108,8 +107,7 @@ */ public final class String - implements java.io.Serializable, Comparable, CharSequence -{ + implements java.io.Serializable, Comparable, CharSequence { /** The value is used for character storage. */ private final char value[]; @@ -3076,5 +3074,53 @@ * guaranteed to be from a pool of unique strings. */ public native String intern(); + + /** + * Seed value used for each alternative hash calculated. + */ + private static final int HASHING_SEED; + + static { + long nanos = System.nanoTime(); + long now = System.currentTimeMillis(); + int SEED_MATERIAL[] = { + System.identityHashCode(String.class), + System.identityHashCode(System.class), + System.identityHashCode(Thread.currentThread()), + (int) (nanos >>> 32), + (int) nanos, + (int) (now >>> 32), + (int) now, + (int) (System.nanoTime() >> 2) + }; + + HASHING_SEED = sun.misc.Hashing.murmur3_32(SEED_MATERIAL); + } + + /** + * Cached value of the hashing algorithm result + */ + private transient int hash32 = 0; + + /** + * {@inheritDoc} + * + *

+ * The hash value will never be zero. + */ + public int hash32() { + int h = hash32; + if (0 == h) { + // harmless data race on hash32 here. + h = sun.misc.Hashing.murmur3_32(HASHING_SEED, value, offset, count); + + // ensure result is not zero to avoid recalcing + h = (0 != h) ? h : 1; + + hash32 = h; + } + + return h; + } }