diff --git a/src/java.base/share/classes/java/util/Currency.java b/src/java.base/share/classes/java/util/Currency.java index 3aa966e83e8..febae04a77b 100644 --- a/src/java.base/share/classes/java/util/Currency.java +++ b/src/java.base/share/classes/java/util/Currency.java @@ -38,6 +38,7 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.function.Supplier; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.spi.CurrencyNameProvider; @@ -141,7 +142,8 @@ public final class Currency implements Serializable { // class data: instance map private static ConcurrentMap instances = new ConcurrentHashMap<>(7); - private static HashSet available; + private static final Supplier> available = + StableValue.supplier(Currency::computeAllCurrencies); // Class data: currency data obtained from currency.data file. // Purpose: @@ -447,7 +449,7 @@ public final class Currency implements Serializable { * @since 1.7 */ public static Set getAvailableCurrencies() { - return new HashSet<>(getCurrencies()); + return new HashSet<>(available.get()); } /** @@ -462,53 +464,52 @@ public final class Currency implements Serializable { * @since 25 */ public static Stream availableCurrencies() { - return getCurrencies().stream(); + return available.get().stream(); } - // Returns the set of available Currencies which are lazily initialized - private static synchronized HashSet getCurrencies() { - if (available == null) { - var sysTime = System.currentTimeMillis(); - available = HashSet.newHashSet(256); + // Builds and returns the set of available Currencies + private static HashSet computeAllCurrencies() { + var sysTime = System.currentTimeMillis(); + HashSet available = HashSet.newHashSet(256); - // Add simple currencies first - for (char c1 = 'A'; c1 <= 'Z'; c1 ++) { - for (char c2 = 'A'; c2 <= 'Z'; c2 ++) { - int tableEntry = getMainTableEntry(c1, c2); - if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK - && tableEntry != INVALID_COUNTRY_ENTRY) { - char finalChar = (char) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) + 'A'); - int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT; - int numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT; - StringBuilder sb = new StringBuilder(); - sb.append(c1); - sb.append(c2); - sb.append(finalChar); - available.add(getInstance(sb.toString(), defaultFractionDigits, numericCode)); - } else if ((tableEntry & COUNTRY_TYPE_MASK) == SPECIAL_CASE_COUNTRY_MASK - && tableEntry != INVALID_COUNTRY_ENTRY - && tableEntry != COUNTRY_WITHOUT_CURRENCY_ENTRY) { - int index = SpecialCaseEntry.toIndex(tableEntry); - SpecialCaseEntry scEntry = specialCasesList.get(index); + for (char c1 = 'A'; c1 <= 'Z'; c1 ++) { + for (char c2 = 'A'; c2 <= 'Z'; c2 ++) { + int tableEntry = getMainTableEntry(c1, c2); + if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK + && tableEntry != INVALID_COUNTRY_ENTRY) { + // Simple Currencies + char finalChar = (char) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) + 'A'); + int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT; + int numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT; + StringBuilder sb = new StringBuilder(); + sb.append(c1); + sb.append(c2); + sb.append(finalChar); + available.add(getInstance(sb.toString(), defaultFractionDigits, numericCode)); + } else if ((tableEntry & COUNTRY_TYPE_MASK) == SPECIAL_CASE_COUNTRY_MASK + && tableEntry != INVALID_COUNTRY_ENTRY + && tableEntry != COUNTRY_WITHOUT_CURRENCY_ENTRY) { + // Special Currencies + int index = SpecialCaseEntry.toIndex(tableEntry); + SpecialCaseEntry scEntry = specialCasesList.get(index); - if (scEntry.cutOverTime == Long.MAX_VALUE - || sysTime < scEntry.cutOverTime) { - available.add(getInstance(scEntry.oldCurrency, - scEntry.oldCurrencyFraction, - scEntry.oldCurrencyNumericCode)); - } else { - available.add(getInstance(scEntry.newCurrency, - scEntry.newCurrencyFraction, - scEntry.newCurrencyNumericCode)); - } + if (scEntry.cutOverTime == Long.MAX_VALUE + || sysTime < scEntry.cutOverTime) { + available.add(getInstance(scEntry.oldCurrency, + scEntry.oldCurrencyFraction, + scEntry.oldCurrencyNumericCode)); + } else { + available.add(getInstance(scEntry.newCurrency, + scEntry.newCurrencyFraction, + scEntry.newCurrencyNumericCode)); } } } + } - // Now add other currencies - for (OtherCurrencyEntry entry : otherCurrenciesList) { - available.add(getInstance(entry.currencyCode)); - } + // Other Currencies + for (OtherCurrencyEntry entry : otherCurrenciesList) { + available.add(getInstance(entry.currencyCode)); } return available; }