[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


Hi,

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 ....

and:

     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