You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by "Sebb (JIRA)" <ji...@apache.org> on 2009/12/11 14:31:18 UTC

[jira] Created: (HARMONY-6405) String.equals() is not thread-safe

String.equals() is not thread-safe
----------------------------------

                 Key: HARMONY-6405
                 URL: https://issues.apache.org/jira/browse/HARMONY-6405
             Project: Harmony
          Issue Type: Bug
    Affects Versions: 5.0M12
            Reporter: Sebb


AFAICT, String.equals() is not thread-safe.

It includes the following code (wrapped for ease of reference):

if (count != s.count     // 1
|| (hashCode != s.hashCode     // 2 
  && hashCode != 0     // 3
  && s.hashCode != 0)) {     //4
return false;     //5

Suppose both Strings refer to the same sequence of characters, so equals() should return true.
Suppose the hashCode has not yet been calculated for "s", but it has been calculated for "this".

At the start:  hashCode != s.hashCode and count == s.count

Line 1 all threads see equality , because count is final.
Line 2 thread A sees hashCode != s.hashCode, i.e. potentially different Strings
Thread B then does s.hashCode() and sets s.hashCode !=0
Line 3 thread A sees hashCode !=0, which is correct
Line 4 thread A sees s.hashCode !=0, which is different from before
Line 5 thread A returns false, whereas thread B will return true.

One possible solution is to fetch the hashCodes into local variables; the values cannot then change unexpectedly.
Although thread A won't see the updated hashCode for "s", that does not matter, because only non-zero codes matter for this comparison.

It should also work if the hashCodes were compared after checking for non-zero, but it would be less fragile (and likely quicker) to fetch each value once.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Assigned: (HARMONY-6405) String.equals() is not thread-safe

Posted by "Tim Ellison (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HARMONY-6405?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Tim Ellison reassigned HARMONY-6405:
------------------------------------

    Assignee: Tim Ellison

> String.equals() is not thread-safe
> ----------------------------------
>
>                 Key: HARMONY-6405
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6405
>             Project: Harmony
>          Issue Type: Bug
>    Affects Versions: 5.0M12
>            Reporter: Sebb
>            Assignee: Tim Ellison
>
> AFAICT, String.equals() is not thread-safe.
> It includes the following code (wrapped for ease of reference):
> if (count != s.count     // 1
> || (hashCode != s.hashCode     // 2 
>   && hashCode != 0     // 3
>   && s.hashCode != 0)) {     //4
> return false;     //5
> Suppose both Strings refer to the same sequence of characters, so equals() should return true.
> Suppose the hashCode has not yet been calculated for "s", but it has been calculated for "this".
> At the start:  hashCode != s.hashCode and count == s.count
> Line 1 all threads see equality , because count is final.
> Line 2 thread A sees hashCode != s.hashCode, i.e. potentially different Strings
> Thread B then does s.hashCode() and sets s.hashCode !=0
> Line 3 thread A sees hashCode !=0, which is correct
> Line 4 thread A sees s.hashCode !=0, which is different from before
> Line 5 thread A returns false, whereas thread B will return true.
> One possible solution is to fetch the hashCodes into local variables; the values cannot then change unexpectedly.
> Although thread A won't see the updated hashCode for "s", that does not matter, because only non-zero codes matter for this comparison.
> It should also work if the hashCodes were compared after checking for non-zero, but it would be less fragile (and likely quicker) to fetch each value once.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (HARMONY-6405) [classlib][luni] String.equals() is not thread-safe

Posted by "Hudson (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HARMONY-6405?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12792450#action_12792450 ] 

Hudson commented on HARMONY-6405:
---------------------------------

Integrated in Harmony-1.5-head-linux-x86_64 #585 (See [http://hudson.zones.apache.org/hudson/job/Harmony-1.5-head-linux-x86_64/585/])
    Fix for  ([classlib][luni] String.equals() is not thread-safe)


> [classlib][luni] String.equals() is not thread-safe
> ---------------------------------------------------
>
>                 Key: HARMONY-6405
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6405
>             Project: Harmony
>          Issue Type: Bug
>    Affects Versions: 5.0M12
>            Reporter: Sebb
>            Assignee: Tim Ellison
>             Fix For: 5.0M13
>
>
> AFAICT, String.equals() is not thread-safe.
> It includes the following code (wrapped for ease of reference):
> if (count != s.count     // 1
> || (hashCode != s.hashCode     // 2 
>   && hashCode != 0     // 3
>   && s.hashCode != 0)) {     //4
> return false;     //5
> Suppose both Strings refer to the same sequence of characters, so equals() should return true.
> Suppose the hashCode has not yet been calculated for "s", but it has been calculated for "this".
> At the start:  hashCode != s.hashCode and count == s.count
> Line 1 all threads see equality , because count is final.
> Line 2 thread A sees hashCode != s.hashCode, i.e. potentially different Strings
> Thread B then does s.hashCode() and sets s.hashCode !=0
> Line 3 thread A sees hashCode !=0, which is correct
> Line 4 thread A sees s.hashCode !=0, which is different from before
> Line 5 thread A returns false, whereas thread B will return true.
> One possible solution is to fetch the hashCodes into local variables; the values cannot then change unexpectedly.
> Although thread A won't see the updated hashCode for "s", that does not matter, because only non-zero codes matter for this comparison.
> It should also work if the hashCodes were compared after checking for non-zero, but it would be less fragile (and likely quicker) to fetch each value once.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Closed: (HARMONY-6405) [classlib][luni] String.equals() is not thread-safe

Posted by "Sebb (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HARMONY-6405?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Sebb closed HARMONY-6405.
-------------------------


Looks good to me

> [classlib][luni] String.equals() is not thread-safe
> ---------------------------------------------------
>
>                 Key: HARMONY-6405
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6405
>             Project: Harmony
>          Issue Type: Bug
>    Affects Versions: 5.0M12
>            Reporter: Sebb
>            Assignee: Tim Ellison
>             Fix For: 5.0M13
>
>
> AFAICT, String.equals() is not thread-safe.
> It includes the following code (wrapped for ease of reference):
> if (count != s.count     // 1
> || (hashCode != s.hashCode     // 2 
>   && hashCode != 0     // 3
>   && s.hashCode != 0)) {     //4
> return false;     //5
> Suppose both Strings refer to the same sequence of characters, so equals() should return true.
> Suppose the hashCode has not yet been calculated for "s", but it has been calculated for "this".
> At the start:  hashCode != s.hashCode and count == s.count
> Line 1 all threads see equality , because count is final.
> Line 2 thread A sees hashCode != s.hashCode, i.e. potentially different Strings
> Thread B then does s.hashCode() and sets s.hashCode !=0
> Line 3 thread A sees hashCode !=0, which is correct
> Line 4 thread A sees s.hashCode !=0, which is different from before
> Line 5 thread A returns false, whereas thread B will return true.
> One possible solution is to fetch the hashCodes into local variables; the values cannot then change unexpectedly.
> Although thread A won't see the updated hashCode for "s", that does not matter, because only non-zero codes matter for this comparison.
> It should also work if the hashCodes were compared after checking for non-zero, but it would be less fragile (and likely quicker) to fetch each value once.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (HARMONY-6405) [classlib][luni] String.equals() is not thread-safe

Posted by "Tim Ellison (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HARMONY-6405?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Tim Ellison updated HARMONY-6405:
---------------------------------

    Summary: [classlib][luni] String.equals() is not thread-safe  (was: String.equals() is not thread-safe)

> [classlib][luni] String.equals() is not thread-safe
> ---------------------------------------------------
>
>                 Key: HARMONY-6405
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6405
>             Project: Harmony
>          Issue Type: Bug
>    Affects Versions: 5.0M12
>            Reporter: Sebb
>            Assignee: Tim Ellison
>
> AFAICT, String.equals() is not thread-safe.
> It includes the following code (wrapped for ease of reference):
> if (count != s.count     // 1
> || (hashCode != s.hashCode     // 2 
>   && hashCode != 0     // 3
>   && s.hashCode != 0)) {     //4
> return false;     //5
> Suppose both Strings refer to the same sequence of characters, so equals() should return true.
> Suppose the hashCode has not yet been calculated for "s", but it has been calculated for "this".
> At the start:  hashCode != s.hashCode and count == s.count
> Line 1 all threads see equality , because count is final.
> Line 2 thread A sees hashCode != s.hashCode, i.e. potentially different Strings
> Thread B then does s.hashCode() and sets s.hashCode !=0
> Line 3 thread A sees hashCode !=0, which is correct
> Line 4 thread A sees s.hashCode !=0, which is different from before
> Line 5 thread A returns false, whereas thread B will return true.
> One possible solution is to fetch the hashCodes into local variables; the values cannot then change unexpectedly.
> Although thread A won't see the updated hashCode for "s", that does not matter, because only non-zero codes matter for this comparison.
> It should also work if the hashCodes were compared after checking for non-zero, but it would be less fragile (and likely quicker) to fetch each value once.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Resolved: (HARMONY-6405) [classlib][luni] String.equals() is not thread-safe

Posted by "Tim Ellison (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HARMONY-6405?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Tim Ellison resolved HARMONY-6405.
----------------------------------

       Resolution: Fixed
    Fix Version/s: 5.0M13

Agreed.  Thanks Sebb, patch applied at repo revision r892226.

Please check this fixes the issue.


> [classlib][luni] String.equals() is not thread-safe
> ---------------------------------------------------
>
>                 Key: HARMONY-6405
>                 URL: https://issues.apache.org/jira/browse/HARMONY-6405
>             Project: Harmony
>          Issue Type: Bug
>    Affects Versions: 5.0M12
>            Reporter: Sebb
>            Assignee: Tim Ellison
>             Fix For: 5.0M13
>
>
> AFAICT, String.equals() is not thread-safe.
> It includes the following code (wrapped for ease of reference):
> if (count != s.count     // 1
> || (hashCode != s.hashCode     // 2 
>   && hashCode != 0     // 3
>   && s.hashCode != 0)) {     //4
> return false;     //5
> Suppose both Strings refer to the same sequence of characters, so equals() should return true.
> Suppose the hashCode has not yet been calculated for "s", but it has been calculated for "this".
> At the start:  hashCode != s.hashCode and count == s.count
> Line 1 all threads see equality , because count is final.
> Line 2 thread A sees hashCode != s.hashCode, i.e. potentially different Strings
> Thread B then does s.hashCode() and sets s.hashCode !=0
> Line 3 thread A sees hashCode !=0, which is correct
> Line 4 thread A sees s.hashCode !=0, which is different from before
> Line 5 thread A returns false, whereas thread B will return true.
> One possible solution is to fetch the hashCodes into local variables; the values cannot then change unexpectedly.
> Although thread A won't see the updated hashCode for "s", that does not matter, because only non-zero codes matter for this comparison.
> It should also work if the hashCodes were compared after checking for non-zero, but it would be less fragile (and likely quicker) to fetch each value once.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.