--- old/src/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java Fri Jan 11 10:35:32 2013 +++ new/src/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java Fri Jan 11 10:35:30 2013 @@ -30,11 +30,10 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.spi.TimeZoneNameProvider; import sun.util.calendar.ZoneInfo; -import sun.util.resources.OpenListResourceBundle; -import sun.util.resources.TimeZoneNamesBundle; /** * Utility class that deals with the localized time zone names @@ -45,15 +44,17 @@ public final class TimeZoneNameUtility { /** - * cache to hold time zone resource bundles. Keyed by Locale + * cache to hold time zone localized strings. Keyed by Locale */ - private static ConcurrentHashMap> cachedBundles = + private static ConcurrentHashMap> cachedZoneData = new ConcurrentHashMap<>(); /** - * cache to hold time zone localized strings. Keyed by Locale + * Cache for managing display names per timezone per locale + * The structure is: + * Map(key=id, value=SoftReference(Map(key=locale, value=displaynames))) */ - private static ConcurrentHashMap> cachedZoneData = + private static final Map>> cachedDisplayNames = new ConcurrentHashMap<>(); /** @@ -82,9 +83,9 @@ } // Performs per-ID retrieval. + Set zoneIDs = LocaleProviderAdapter.forJRE().getLocaleResources(locale).getZoneIDs(); List zones = new LinkedList<>(); - OpenListResourceBundle rb = getBundle(locale); - for (String key : rb.keySet()) { + for (String key : zoneIDs) { String[] names = retrieveDisplayNamesImpl(key, locale); if (names != null) { zones.add(names); @@ -137,20 +138,31 @@ private static String[] retrieveDisplayNamesImpl(String id, Locale locale) { LocaleServiceProviderPool pool = LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class); - return pool.getLocalizedObject(TimeZoneNameArrayGetter.INSTANCE, locale, id); - } - private static TimeZoneNamesBundle getBundle(Locale locale) { - TimeZoneNamesBundle rb; - SoftReference data = cachedBundles.get(locale); - - if (data == null || ((rb = data.get()) == null)) { - rb = LocaleProviderAdapter.forJRE().getLocaleData().getTimeZoneNames(locale); - data = new SoftReference<>(rb); - cachedBundles.put(locale, data); + SoftReference> ref = cachedDisplayNames.get(id); + if (ref != null) { + Map perLocale = ref.get(); + if (perLocale != null) { + String[] names = perLocale.get(locale); + if (names != null) { + return names; + } + names = pool.getLocalizedObject(TimeZoneNameArrayGetter.INSTANCE, locale, id); + if (names != null) { + perLocale.put(locale, names); + } + return names; + } } - return rb; + String[] names = pool.getLocalizedObject(TimeZoneNameArrayGetter.INSTANCE, locale, id); + if (names != null) { + Map perLocale = new ConcurrentHashMap<>(); + perLocale.put(locale, names); + ref = new SoftReference<>(perLocale); + cachedDisplayNames.put(id, ref); + } + return names; } /**