< prev index next >

src/java.base/share/classes/java/util/SimpleTimeZone.java

Print this page

        

@@ -546,18 +546,17 @@
     int getOffsets(long date, int[] offsets) {
         int offset = rawOffset;
 
       computeOffset:
         if (useDaylight) {
-            synchronized (this) {
-                if (cacheStart != 0) {
-                    if (date >= cacheStart && date < cacheEnd) {
+            Cache cache = this.cache;
+            if (cache != null) {
+                if (date >= cache.start && date < cache.end) {
                         offset += dstSavings;
                         break computeOffset;
                     }
                 }
-            }
             BaseCalendar cal = date >= GregorianCalendar.DEFAULT_GREGORIAN_CUTOVER ?
                 gcal : (BaseCalendar) CalendarSystem.forName("julian");
             BaseCalendar.Date cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.NO_TIMEZONE);
             // Get the year in local time
             cal.getCalendarDate(date + rawOffset, cdate);

@@ -669,33 +668,28 @@
 
         return getOffset(cal, cdate, y, time);
     }
 
     private int getOffset(BaseCalendar cal, BaseCalendar.Date cdate, int year, long time) {
-        synchronized (this) {
-            if (cacheStart != 0) {
-                if (time >= cacheStart && time < cacheEnd) {
+        Cache cache = this.cache;
+        if (cache != null) {
+            if (time >= cache.start && time < cache.end) {
                     return rawOffset + dstSavings;
                 }
-                if (year == cacheYear) {
+            if (year == cache.year) {
                     return rawOffset;
                 }
             }
-        }
 
         long start = getStart(cal, cdate, year);
         long end = getEnd(cal, cdate, year);
         int offset = rawOffset;
         if (start <= end) {
             if (time >= start && time < end) {
                 offset += dstSavings;
             }
-            synchronized (this) {
-                cacheYear = year;
-                cacheStart = start;
-                cacheEnd = end;
-            }
+            this.cache = new Cache(year, start, end);
         } else {
             if (time < end) {
                 // TODO: support Gregorian cutover. The previous year
                 // may be in the other calendar system.
                 start = getStart(cal, cdate, year - 1);

@@ -709,16 +703,11 @@
                 if (time < end) {
                     offset += dstSavings;
                 }
             }
             if (start <= end) {
-                synchronized (this) {
-                    // The start and end transitions are in multiple years.
-                    cacheYear = (long) startYear - 1;
-                    cacheStart = start;
-                    cacheEnd = end;
-                }
+                this.cache = new Cache((long) startYear - 1, start, end);
             }
         }
         return offset;
     }
 

@@ -874,11 +863,11 @@
 
     /**
      * Generates the hash code for the SimpleDateFormat object.
      * @return the hash code for this object
      */
-    public synchronized int hashCode()
+    public int hashCode()
     {
         return startMonth ^ startDay ^ startDayOfWeek ^ startTime ^
             endMonth ^ endDay ^ endDayOfWeek ^ endTime ^ rawOffset;
     }
 

@@ -1199,23 +1188,31 @@
 
     private static final Gregorian gcal = CalendarSystem.getGregorianCalendar();
 
     /**
      * Cache values representing a single period of daylight saving
-     * time. When the cache values are valid, cacheStart is the start
-     * time (inclusive) of daylight saving time and cacheEnd is the
-     * end time (exclusive).
+     * time. Cache.start is the start time (inclusive) of daylight
+     * saving time and Cache.end is the end time (exclusive).
      *
-     * cacheYear has a year value if both cacheStart and cacheEnd are
-     * in the same year. cacheYear is set to startYear - 1 if
-     * cacheStart and cacheEnd are in different years. cacheStart is 0
-     * if the cache values are void. cacheYear is a long to support
-     * Integer.MIN_VALUE - 1 (JCK requirement).
-     */
-    private transient long cacheYear;
-    private transient long cacheStart;
-    private transient long cacheEnd;
+     * Cache.year has a year value if both Cache.start and Cache.end are
+     * in the same year. Cache.year is set to startYear - 1 if
+     * Cache.start and Cache.end are in different years.
+     * Cache.year is a long to support Integer.MIN_VALUE - 1 (JCK requirement).
+     */
+    private static final class Cache {
+        final long year;
+        final long start;
+        final long end;
+
+        Cache(long year, long start, long end) {
+            this.year = year;
+            this.start = start;
+            this.end = end;
+        }
+    }
+
+    private transient volatile Cache cache;
 
     /**
      * Constants specifying values of startMode and endMode.
      */
     private static final int DOM_MODE          = 1; // Exact day of month, "Mar 1"

@@ -1280,13 +1277,12 @@
     private int serialVersionOnStream = currentSerialVersion;
 
     // Maximum number of rules.
     private static final int MAX_RULE_NUM = 6;
 
-    private synchronized void invalidateCache() {
-        cacheYear = startYear - 1;
-        cacheStart = cacheEnd = 0;
+    private void invalidateCache() {
+        cache = null;
     }
 
     //----------------------------------------------------------------------
     // Rule representation
     //
< prev index next >