4808233: "Locale" not thread-safe
authornaoto
Tue, 13 Dec 2011 15:41:47 -0800
changeset 11282 2c8538c9daa6
parent 11281 58ecbc808474
child 11283 e38a7eecd5fc
4808233: "Locale" not thread-safe Reviewed-by: okutsu
jdk/src/share/classes/java/util/Locale.java
--- a/jdk/src/share/classes/java/util/Locale.java	Mon Dec 12 08:17:28 2011 -0800
+++ b/jdk/src/share/classes/java/util/Locale.java	Tue Dec 13 15:41:47 2011 -0800
@@ -737,10 +737,6 @@
      */
     public static Locale getDefault() {
         // do not synchronize this method - see 4071298
-        // it's OK if more than one default locale happens to be created
-        if (defaultLocale == null) {
-            initDefault();
-        }
         return defaultLocale;
     }
 
@@ -762,16 +758,23 @@
      */
     public static Locale getDefault(Locale.Category category) {
         // do not synchronize this method - see 4071298
-        // it's OK if more than one default locale happens to be created
         switch (category) {
         case DISPLAY:
             if (defaultDisplayLocale == null) {
-                initDefault(category);
+                synchronized(Locale.class) {
+                    if (defaultDisplayLocale == null) {
+                        defaultDisplayLocale = initDefault(category);
+                    }
+                }
             }
             return defaultDisplayLocale;
         case FORMAT:
             if (defaultFormatLocale == null) {
-                initDefault(category);
+                synchronized(Locale.class) {
+                    if (defaultFormatLocale == null) {
+                        defaultFormatLocale = initDefault(category);
+                    }
+                }
             }
             return defaultFormatLocale;
         default:
@@ -780,7 +783,7 @@
         return getDefault();
     }
 
-    private static void initDefault() {
+    private static Locale initDefault() {
         String language, region, script, country, variant;
         language = AccessController.doPrivileged(
             new GetPropertyAction("user.language", "en"));
@@ -806,16 +809,12 @@
             variant = AccessController.doPrivileged(
                 new GetPropertyAction("user.variant", ""));
         }
-        defaultLocale = getInstance(language, script, country, variant, null);
+
+        return getInstance(language, script, country, variant, null);
     }
 
-    private static void initDefault(Locale.Category category) {
-        // make sure defaultLocale is initialized
-        if (defaultLocale == null) {
-            initDefault();
-        }
-
-        Locale defaultCategoryLocale = getInstance(
+    private static Locale initDefault(Locale.Category category) {
+        return getInstance(
             AccessController.doPrivileged(
                 new GetPropertyAction(category.languageKey, defaultLocale.getLanguage())),
             AccessController.doPrivileged(
@@ -825,15 +824,6 @@
             AccessController.doPrivileged(
                 new GetPropertyAction(category.variantKey, defaultLocale.getVariant())),
             null);
-
-        switch (category) {
-        case DISPLAY:
-            defaultDisplayLocale = defaultCategoryLocale;
-            break;
-        case FORMAT:
-            defaultFormatLocale = defaultCategoryLocale;
-            break;
-        }
     }
 
     /**
@@ -1916,9 +1906,9 @@
      */
     private transient volatile int hashCodeValue = 0;
 
-    private static Locale defaultLocale = null;
-    private static Locale defaultDisplayLocale = null;
-    private static Locale defaultFormatLocale = null;
+    private volatile static Locale defaultLocale = initDefault();
+    private volatile static Locale defaultDisplayLocale = null;
+    private volatile static Locale defaultFormatLocale = null;
 
     /**
      * Return an array of the display names of the variant.