3838import java .time .format .DateTimeParseException ;
3939import java .util .concurrent .ConcurrentHashMap ;
4040import java .util .concurrent .ConcurrentMap ;
41+ import java .util .function .Supplier ;
4142import java .util .regex .Pattern ;
4243import java .util .regex .Matcher ;
4344import java .util .spi .CurrencyNameProvider ;
@@ -141,7 +142,8 @@ public final class Currency implements Serializable {
141142 // class data: instance map
142143
143144 private static ConcurrentMap <String , Currency > instances = new ConcurrentHashMap <>(7 );
144- private static HashSet <Currency > available ;
145+ private static final Supplier <HashSet <Currency >> available =
146+ StableValue .supplier (Currency ::computeAllCurrencies );
145147
146148 // Class data: currency data obtained from currency.data file.
147149 // Purpose:
@@ -447,7 +449,7 @@ public static Currency getInstance(Locale locale) {
447449 * @since 1.7
448450 */
449451 public static Set <Currency > getAvailableCurrencies () {
450- return new HashSet <>(getCurrencies ());
452+ return new HashSet <>(available . get ());
451453 }
452454
453455 /**
@@ -462,53 +464,52 @@ public static Set<Currency> getAvailableCurrencies() {
462464 * @since 25
463465 */
464466 public static Stream <Currency > availableCurrencies () {
465- return getCurrencies ().stream ();
467+ return available . get ().stream ();
466468 }
467469
468- // Returns the set of available Currencies which are lazily initialized
469- private static synchronized HashSet <Currency > getCurrencies () {
470- if (available == null ) {
471- var sysTime = System .currentTimeMillis ();
472- available = HashSet .newHashSet (256 );
473-
474- // Add simple currencies first
475- for (char c1 = 'A' ; c1 <= 'Z' ; c1 ++) {
476- for (char c2 = 'A' ; c2 <= 'Z' ; c2 ++) {
477- int tableEntry = getMainTableEntry (c1 , c2 );
478- if ((tableEntry & COUNTRY_TYPE_MASK ) == SIMPLE_CASE_COUNTRY_MASK
479- && tableEntry != INVALID_COUNTRY_ENTRY ) {
480- char finalChar = (char ) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK ) + 'A' );
481- int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK ) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT ;
482- int numericCode = (tableEntry & NUMERIC_CODE_MASK ) >> NUMERIC_CODE_SHIFT ;
483- StringBuilder sb = new StringBuilder ();
484- sb .append (c1 );
485- sb .append (c2 );
486- sb .append (finalChar );
487- available .add (getInstance (sb .toString (), defaultFractionDigits , numericCode ));
488- } else if ((tableEntry & COUNTRY_TYPE_MASK ) == SPECIAL_CASE_COUNTRY_MASK
489- && tableEntry != INVALID_COUNTRY_ENTRY
490- && tableEntry != COUNTRY_WITHOUT_CURRENCY_ENTRY ) {
491- int index = SpecialCaseEntry .toIndex (tableEntry );
492- SpecialCaseEntry scEntry = specialCasesList .get (index );
493-
494- if (scEntry .cutOverTime == Long .MAX_VALUE
495- || sysTime < scEntry .cutOverTime ) {
496- available .add (getInstance (scEntry .oldCurrency ,
497- scEntry .oldCurrencyFraction ,
498- scEntry .oldCurrencyNumericCode ));
499- } else {
500- available .add (getInstance (scEntry .newCurrency ,
501- scEntry .newCurrencyFraction ,
502- scEntry .newCurrencyNumericCode ));
503- }
470+ // Builds and returns the set of available Currencies
471+ private static HashSet <Currency > computeAllCurrencies () {
472+ var sysTime = System .currentTimeMillis ();
473+ HashSet <Currency > available = HashSet .newHashSet (256 );
474+
475+ for (char c1 = 'A' ; c1 <= 'Z' ; c1 ++) {
476+ for (char c2 = 'A' ; c2 <= 'Z' ; c2 ++) {
477+ int tableEntry = getMainTableEntry (c1 , c2 );
478+ if ((tableEntry & COUNTRY_TYPE_MASK ) == SIMPLE_CASE_COUNTRY_MASK
479+ && tableEntry != INVALID_COUNTRY_ENTRY ) {
480+ // Simple Currencies
481+ char finalChar = (char ) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK ) + 'A' );
482+ int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK ) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT ;
483+ int numericCode = (tableEntry & NUMERIC_CODE_MASK ) >> NUMERIC_CODE_SHIFT ;
484+ StringBuilder sb = new StringBuilder ();
485+ sb .append (c1 );
486+ sb .append (c2 );
487+ sb .append (finalChar );
488+ available .add (getInstance (sb .toString (), defaultFractionDigits , numericCode ));
489+ } else if ((tableEntry & COUNTRY_TYPE_MASK ) == SPECIAL_CASE_COUNTRY_MASK
490+ && tableEntry != INVALID_COUNTRY_ENTRY
491+ && tableEntry != COUNTRY_WITHOUT_CURRENCY_ENTRY ) {
492+ // Special Currencies
493+ int index = SpecialCaseEntry .toIndex (tableEntry );
494+ SpecialCaseEntry scEntry = specialCasesList .get (index );
495+
496+ if (scEntry .cutOverTime == Long .MAX_VALUE
497+ || sysTime < scEntry .cutOverTime ) {
498+ available .add (getInstance (scEntry .oldCurrency ,
499+ scEntry .oldCurrencyFraction ,
500+ scEntry .oldCurrencyNumericCode ));
501+ } else {
502+ available .add (getInstance (scEntry .newCurrency ,
503+ scEntry .newCurrencyFraction ,
504+ scEntry .newCurrencyNumericCode ));
504505 }
505506 }
506507 }
508+ }
507509
508- // Now add other currencies
509- for (OtherCurrencyEntry entry : otherCurrenciesList ) {
510- available .add (getInstance (entry .currencyCode ));
511- }
510+ // Other Currencies
511+ for (OtherCurrencyEntry entry : otherCurrenciesList ) {
512+ available .add (getInstance (entry .currencyCode ));
512513 }
513514 return available ;
514515 }
0 commit comments