mirror of
https://github.com/apache/commons-lang.git
synced 2025-02-13 05:25:20 +00:00
Use concurrent instead of synchronization; Javadoc
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1077984 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
1e2b9eb078
commit
c21a7a26c0
@ -19,12 +19,12 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* <p>Operations to assist when working with a {@link Locale}.</p>
|
||||
@ -39,21 +39,13 @@
|
||||
*/
|
||||
public class LocaleUtils {
|
||||
|
||||
/** Unmodifiable list of available locales. */
|
||||
//@GuardedBy("this")
|
||||
private static List<Locale> cAvailableLocaleList; // lazily created by availableLocaleList()
|
||||
/** Concurrent map of language locales by country. */
|
||||
private static final ConcurrentMap<String, List<Locale>> cLanguagesByCountry =
|
||||
new ConcurrentHashMap<String, List<Locale>>();
|
||||
|
||||
/** Unmodifiable set of available locales. */
|
||||
//@GuardedBy("this")
|
||||
private static Set<Locale> cAvailableLocaleSet; // lazily created by availableLocaleSet()
|
||||
|
||||
/** Unmodifiable map of language locales by country. */
|
||||
private static final Map<String, List<Locale>> cLanguagesByCountry =
|
||||
Collections.synchronizedMap(new HashMap<String, List<Locale>>());
|
||||
|
||||
/** Unmodifiable map of country locales by language. */
|
||||
private static final Map<String, List<Locale>> cCountriesByLanguage =
|
||||
Collections.synchronizedMap(new HashMap<String, List<Locale>>());
|
||||
/** Concurrent map of country locales by language. */
|
||||
private static final ConcurrentMap<String, List<Locale>> cCountriesByLanguage =
|
||||
new ConcurrentHashMap<String, List<Locale>>();
|
||||
|
||||
/**
|
||||
* <p><code>LocaleUtils</code> instances should NOT be constructed in standard programming.
|
||||
@ -143,7 +135,7 @@ public static Locale toLocale(String str) {
|
||||
* </pre>
|
||||
*
|
||||
* @param locale the locale to start from
|
||||
* @return the unmodifiable list of Locale objects, 0 being locale, never null
|
||||
* @return the unmodifiable list of Locale objects, 0 being locale, not null
|
||||
*/
|
||||
public static List<Locale> localeLookupList(Locale locale) {
|
||||
return localeLookupList(locale, locale);
|
||||
@ -165,7 +157,7 @@ public static List<Locale> localeLookupList(Locale locale) {
|
||||
*
|
||||
* @param locale the locale to start from, null returns empty list
|
||||
* @param defaultLocale the default locale to use if no other is found
|
||||
* @return the unmodifiable list of Locale objects, 0 being locale, never null
|
||||
* @return the unmodifiable list of Locale objects, 0 being locale, not null
|
||||
*/
|
||||
public static List<Locale> localeLookupList(Locale locale, Locale defaultLocale) {
|
||||
List<Locale> list = new ArrayList<Locale>(4);
|
||||
@ -195,22 +187,7 @@ public static List<Locale> localeLookupList(Locale locale, Locale defaultLocale)
|
||||
* @return the unmodifiable list of available locales
|
||||
*/
|
||||
public static List<Locale> availableLocaleList() {
|
||||
if(cAvailableLocaleList == null) {
|
||||
initAvailableLocaleList();
|
||||
}
|
||||
return cAvailableLocaleList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the availableLocaleList. It is separate from availableLocaleList()
|
||||
* to avoid the synchronized block affecting normal use, yet synchronized and
|
||||
* lazy loading to avoid a static block affecting other methods in this class.
|
||||
*/
|
||||
private static synchronized void initAvailableLocaleList() {
|
||||
if(cAvailableLocaleList == null) {
|
||||
List<Locale> list = Arrays.asList(Locale.getAvailableLocales());
|
||||
cAvailableLocaleList = Collections.unmodifiableList(list);
|
||||
}
|
||||
return SyncAvoid.AVAILABLE_LOCALE_LIST;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@ -224,21 +201,7 @@ private static synchronized void initAvailableLocaleList() {
|
||||
* @return the unmodifiable set of available locales
|
||||
*/
|
||||
public static Set<Locale> availableLocaleSet() {
|
||||
if(cAvailableLocaleSet == null) {
|
||||
initAvailableLocaleSet();
|
||||
}
|
||||
return cAvailableLocaleSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the availableLocaleSet. It is separate from availableLocaleSet()
|
||||
* to avoid the synchronized block affecting normal use, yet synchronized and
|
||||
* lazy loading to avoid a static block affecting other methods in this class.
|
||||
*/
|
||||
private static synchronized void initAvailableLocaleSet() {
|
||||
if(cAvailableLocaleSet == null) {
|
||||
cAvailableLocaleSet = Collections.unmodifiableSet( new HashSet<Locale>(availableLocaleList()) );
|
||||
}
|
||||
return SyncAvoid.AVAILABLE_LOCALE_SET;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@ -260,26 +223,26 @@ public static boolean isAvailableLocale(Locale locale) {
|
||||
* languages available for that country. Variant locales are removed.</p>
|
||||
*
|
||||
* @param countryCode the 2 letter country code, null returns empty
|
||||
* @return an unmodifiable List of Locale objects, never null
|
||||
* @return an unmodifiable List of Locale objects, not null
|
||||
*/
|
||||
public static List<Locale> languagesByCountry(String countryCode) {
|
||||
List<Locale> langs = cLanguagesByCountry.get(countryCode); //syncd
|
||||
if (countryCode == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Locale> langs = cLanguagesByCountry.get(countryCode);
|
||||
if (langs == null) {
|
||||
if (countryCode != null) {
|
||||
langs = new ArrayList<Locale>();
|
||||
List<Locale> locales = availableLocaleList();
|
||||
for (int i = 0; i < locales.size(); i++) {
|
||||
Locale locale = locales.get(i);
|
||||
if (countryCode.equals(locale.getCountry()) &&
|
||||
locale.getVariant().length() == 0) {
|
||||
langs.add(locale);
|
||||
}
|
||||
langs = new ArrayList<Locale>();
|
||||
List<Locale> locales = availableLocaleList();
|
||||
for (int i = 0; i < locales.size(); i++) {
|
||||
Locale locale = locales.get(i);
|
||||
if (countryCode.equals(locale.getCountry()) &&
|
||||
locale.getVariant().length() == 0) {
|
||||
langs.add(locale);
|
||||
}
|
||||
langs = Collections.unmodifiableList(langs);
|
||||
} else {
|
||||
langs = Collections.emptyList();
|
||||
}
|
||||
cLanguagesByCountry.put(countryCode, langs); //syncd
|
||||
langs = Collections.unmodifiableList(langs);
|
||||
cLanguagesByCountry.putIfAbsent(countryCode, langs);
|
||||
langs = cLanguagesByCountry.get(countryCode);
|
||||
}
|
||||
return langs;
|
||||
}
|
||||
@ -292,29 +255,44 @@ public static List<Locale> languagesByCountry(String countryCode) {
|
||||
* countries available for that language. Variant locales are removed.</p>
|
||||
*
|
||||
* @param languageCode the 2 letter language code, null returns empty
|
||||
* @return an unmodifiable List of Locale objects, never null
|
||||
* @return an unmodifiable List of Locale objects, not null
|
||||
*/
|
||||
public static List<Locale> countriesByLanguage(String languageCode) {
|
||||
List<Locale> countries = cCountriesByLanguage.get(languageCode); //syncd
|
||||
if (languageCode == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Locale> countries = cCountriesByLanguage.get(languageCode);
|
||||
if (countries == null) {
|
||||
if (languageCode != null) {
|
||||
countries = new ArrayList<Locale>();
|
||||
List<Locale> locales = availableLocaleList();
|
||||
for (int i = 0; i < locales.size(); i++) {
|
||||
Locale locale = locales.get(i);
|
||||
if (languageCode.equals(locale.getLanguage()) &&
|
||||
locale.getCountry().length() != 0 &&
|
||||
locale.getVariant().length() == 0) {
|
||||
countries.add(locale);
|
||||
}
|
||||
countries = new ArrayList<Locale>();
|
||||
List<Locale> locales = availableLocaleList();
|
||||
for (int i = 0; i < locales.size(); i++) {
|
||||
Locale locale = locales.get(i);
|
||||
if (languageCode.equals(locale.getLanguage()) &&
|
||||
locale.getCountry().length() != 0 &&
|
||||
locale.getVariant().length() == 0) {
|
||||
countries.add(locale);
|
||||
}
|
||||
countries = Collections.unmodifiableList(countries);
|
||||
} else {
|
||||
countries = Collections.emptyList();
|
||||
}
|
||||
cCountriesByLanguage.put(languageCode, countries); //syncd
|
||||
countries = Collections.unmodifiableList(countries);
|
||||
cCountriesByLanguage.putIfAbsent(languageCode, countries);
|
||||
countries = cCountriesByLanguage.get(languageCode);
|
||||
}
|
||||
return countries;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// class to avoid synchronization
|
||||
static class SyncAvoid {
|
||||
/** Unmodifiable list of available locales. */
|
||||
private static List<Locale> AVAILABLE_LOCALE_LIST;
|
||||
/** Unmodifiable set of available locales. */
|
||||
private static Set<Locale> AVAILABLE_LOCALE_SET;
|
||||
|
||||
static {
|
||||
List<Locale> list = new ArrayList<Locale>(Arrays.asList(Locale.getAvailableLocales())); // extra safe
|
||||
AVAILABLE_LOCALE_LIST = Collections.unmodifiableList(list);
|
||||
AVAILABLE_LOCALE_SET = Collections.unmodifiableSet(new HashSet<Locale>(availableLocaleList()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user