Skip to content

Commit b6b5ac1

Browse files
author
Justin Lu
committed
8348351: Improve lazy initialization of the available currencies set
Reviewed-by: liach, naoto
1 parent 2595fcc commit b6b5ac1

File tree

1 file changed

+44
-43
lines changed

1 file changed

+44
-43
lines changed

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

Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import java.time.format.DateTimeParseException;
3939
import java.util.concurrent.ConcurrentHashMap;
4040
import java.util.concurrent.ConcurrentMap;
41+
import java.util.function.Supplier;
4142
import java.util.regex.Pattern;
4243
import java.util.regex.Matcher;
4344
import 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

Comments
 (0)