Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 44 additions & 43 deletions src/java.base/share/classes/java/util/Currency.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
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;
Expand Down Expand Up @@ -141,7 +142,8 @@ public final class Currency implements Serializable {
// class data: instance map

private static ConcurrentMap<String, Currency> instances = new ConcurrentHashMap<>(7);
private static HashSet<Currency> available;
private static final Supplier<HashSet<Currency>> available =
StableValue.supplier(Currency::computeAllCurrencies);

// Class data: currency data obtained from currency.data file.
// Purpose:
Expand Down Expand Up @@ -447,7 +449,7 @@ public static Currency getInstance(Locale locale) {
* @since 1.7
*/
public static Set<Currency> getAvailableCurrencies() {
return new HashSet<>(getCurrencies());
return new HashSet<>(available.get());
}

/**
Expand All @@ -462,53 +464,52 @@ public static Set<Currency> getAvailableCurrencies() {
* @since 25
*/
public static Stream<Currency> availableCurrencies() {
return getCurrencies().stream();
return available.get().stream();
}

// Returns the set of available Currencies which are lazily initialized
private static synchronized HashSet<Currency> getCurrencies() {
if (available == null) {
var sysTime = System.currentTimeMillis();
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);

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));
}
// Builds and returns the set of available Currencies
private static HashSet<Currency> computeAllCurrencies() {
var sysTime = System.currentTimeMillis();
HashSet<Currency> available = HashSet.newHashSet(256);

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));
}
}
}
}

// 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;
}
Expand Down