[concurrency-interest] Does JDK 9 String.hashCode() have a bug?

Peter Levart peter.levart at gmail.com
Wed Sep 28 06:33:08 EDT 2016


I would like to discuss the implementation of String.hashCode() method 
in the light of JMM. Here it is (the recent one from JDK 9 which 
includes implementation of compact strings):

     public int hashCode() {
         if (hash == 0 && value.length > 0) {
             hash = isLatin1() ? StringLatin1.hashCode(value)
                               : StringUTF16.hashCode(value);
         return hash;

Here, 'hash' is a plain instance field in String. Suppose we have a 
freshly constructed non-zero length String object, whose reference 's' 
is accessible to two threads and each of them concurrently invokes 
hashCode() on it:

Thread 1:

int h1 = s.hashCode();

Thread 2:

int h2 = s.hashCode();

Suppose also that the isLatin1() ? StringLatin1.hashCode(value) : 
StringUTF16.hashCode(value) computation returns a non-zero value.

Is it possible that the outcome (h1, h2) is either (0, hc) or (hc, 0) 
where the hc is the non-zero result of above mentioned computation?

According to JMM, I think it is. Since there is no synchronization 
between a write w(hash, hc) by one thread and two reads r1(value):v1 and 
r2(value):v2 by the other thread that correspond to program lines:

     if (hash == 0 ....


     return hash;

...the reads may or may not see the write independently. So there is a 
possibility that v1 == hc and v2 == 0.

Am I right and should this be fixed?

Note that JDK 8 code is different. It does not have this problem:

public int hashCode() {
         int h = hash;
         if (h == 0) {
             for (char v : value) {
                 h = 31 * h + v;
             if (h != 0) {
                 hash = h;
         return h;

Regards, Peter

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20160928/38190e8b/attachment.html>

More information about the Concurrency-interest mailing list