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

Aleksey Shipilev shade at redhat.com
Wed Sep 28 08:07:01 EDT 2016


On 09/28/2016 01:55 PM, Jonas Konrad wrote:
> Take this example:
> 
> class Race {
>     String s = "a";
>     void writer() { s = "b"; }
> 
>     void reader() {
>         String tmp = s;
>         assert s.hashCode() == s.hashCode();
>     }
> }
> 
> class String {
>     final char[] value; int hash;
> 
>     int hashCode() {
>         int h = hash;
>         if (h == 0) {
>             hash = h = computeHashCode(value);
>         }
>         return h;
>     }
> }
> 
> In the JMM, can't that assertion fail? 

Well, it can fail, because you have the prior race on Race.s, and you
might be comparing the hashcodes from two different Strings to begin
with. Obviously, this cannot be recovered in String.hashCode:

     void reader() {
         String tmp = s;
         assert s.hashCode() == s.hashCode();
     }

...but if you were to write:

     void reader() {
         String tmp = s;
         assert tmp.hashCode() == tmp.hashCode();
     }

...then it cannot fail, because String.hashCode() as stated cannot
return 0. (This is also one of many reasons why compilers cannot
generally replace local variables with memory reads, exposing users to
races). String.hashCode above will take a corrective action it if
happens to read (hash == 0), and return the recomputed one.

Thanks,
-Aleksey


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20160928/2f2b9412/attachment-0001.sig>


More information about the Concurrency-interest mailing list