src/java.base/share/classes/java/lang/String.java
changeset 54486 7fd299216e97
parent 54378 7c576e4d0afa
child 54550 5fa7fbddfe9d
equal deleted inserted replaced
54485:ddc19ea5059c 54486:7fd299216e97
   162     private final byte coder;
   162     private final byte coder;
   163 
   163 
   164     /** Cache the hash code for the string */
   164     /** Cache the hash code for the string */
   165     private int hash; // Default to 0
   165     private int hash; // Default to 0
   166 
   166 
       
   167     /**
       
   168      * Cache if the hash has been calculated as actually being zero, enabling
       
   169      * us to avoid recalculating this.
       
   170      */
       
   171     private boolean hashIsZero; // Default to false;
       
   172 
   167     /** use serialVersionUID from JDK 1.0.2 for interoperability */
   173     /** use serialVersionUID from JDK 1.0.2 for interoperability */
   168     private static final long serialVersionUID = -6849794470754667710L;
   174     private static final long serialVersionUID = -6849794470754667710L;
   169 
   175 
   170     /**
   176     /**
   171      * If String compaction is disabled, the bytes in {@code value} are
   177      * If String compaction is disabled, the bytes in {@code value} are
  1506      * (The hash value of the empty string is zero.)
  1512      * (The hash value of the empty string is zero.)
  1507      *
  1513      *
  1508      * @return  a hash code value for this object.
  1514      * @return  a hash code value for this object.
  1509      */
  1515      */
  1510     public int hashCode() {
  1516     public int hashCode() {
       
  1517         // The hash or hashIsZero fields are subject to a benign data race,
       
  1518         // making it crucial to ensure that any observable result of the
       
  1519         // calculation in this method stays correct under any possible read of
       
  1520         // these fields. Necessary restrictions to allow this to be correct
       
  1521         // without explicit memory fences or similar concurrency primitives is
       
  1522         // that we can ever only write to one of these two fields for a given
       
  1523         // String instance, and that the computation is idempotent and derived
       
  1524         // from immutable state
  1511         int h = hash;
  1525         int h = hash;
  1512         if (h == 0 && value.length > 0) {
  1526         if (h == 0 && !hashIsZero) {
  1513             h = isLatin1() ? StringLatin1.hashCode(value)
  1527             h = isLatin1() ? StringLatin1.hashCode(value)
  1514                            : StringUTF16.hashCode(value);
  1528                            : StringUTF16.hashCode(value);
  1515             // Avoid issuing a store if the calculated value is also zero:
  1529             if (h == 0) {
  1516             // in addition to a minor performance benefit, this allows storing
  1530                 hashIsZero = true;
  1517             // Strings with zero hash code in read-only memory.
  1531             } else {
  1518             if (h != 0) {
       
  1519                 hash = h;
  1532                 hash = h;
  1520             }
  1533             }
  1521         }
  1534         }
  1522         return h;
  1535         return h;
  1523     }
  1536     }