mirror of
https://github.com/apache/commons-lang.git
synced 2025-02-19 00:20:58 +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.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
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>
|
* <p>Operations to assist when working with a {@link Locale}.</p>
|
||||||
@ -39,21 +39,13 @@
|
|||||||
*/
|
*/
|
||||||
public class LocaleUtils {
|
public class LocaleUtils {
|
||||||
|
|
||||||
/** Unmodifiable list of available locales. */
|
/** Concurrent map of language locales by country. */
|
||||||
//@GuardedBy("this")
|
private static final ConcurrentMap<String, List<Locale>> cLanguagesByCountry =
|
||||||
private static List<Locale> cAvailableLocaleList; // lazily created by availableLocaleList()
|
new ConcurrentHashMap<String, List<Locale>>();
|
||||||
|
|
||||||
/** Unmodifiable set of available locales. */
|
/** Concurrent map of country locales by language. */
|
||||||
//@GuardedBy("this")
|
private static final ConcurrentMap<String, List<Locale>> cCountriesByLanguage =
|
||||||
private static Set<Locale> cAvailableLocaleSet; // lazily created by availableLocaleSet()
|
new ConcurrentHashMap<String, List<Locale>>();
|
||||||
|
|
||||||
/** 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>>());
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p><code>LocaleUtils</code> instances should NOT be constructed in standard programming.
|
* <p><code>LocaleUtils</code> instances should NOT be constructed in standard programming.
|
||||||
@ -143,7 +135,7 @@ public static Locale toLocale(String str) {
|
|||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param locale the locale to start from
|
* @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) {
|
public static List<Locale> localeLookupList(Locale locale) {
|
||||||
return 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 locale the locale to start from, null returns empty list
|
||||||
* @param defaultLocale the default locale to use if no other is found
|
* @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) {
|
public static List<Locale> localeLookupList(Locale locale, Locale defaultLocale) {
|
||||||
List<Locale> list = new ArrayList<Locale>(4);
|
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
|
* @return the unmodifiable list of available locales
|
||||||
*/
|
*/
|
||||||
public static List<Locale> availableLocaleList() {
|
public static List<Locale> availableLocaleList() {
|
||||||
if(cAvailableLocaleList == null) {
|
return SyncAvoid.AVAILABLE_LOCALE_LIST;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
@ -224,21 +201,7 @@ private static synchronized void initAvailableLocaleList() {
|
|||||||
* @return the unmodifiable set of available locales
|
* @return the unmodifiable set of available locales
|
||||||
*/
|
*/
|
||||||
public static Set<Locale> availableLocaleSet() {
|
public static Set<Locale> availableLocaleSet() {
|
||||||
if(cAvailableLocaleSet == null) {
|
return SyncAvoid.AVAILABLE_LOCALE_SET;
|
||||||
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()) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
@ -260,12 +223,14 @@ public static boolean isAvailableLocale(Locale locale) {
|
|||||||
* languages available for that country. Variant locales are removed.</p>
|
* languages available for that country. Variant locales are removed.</p>
|
||||||
*
|
*
|
||||||
* @param countryCode the 2 letter country code, null returns empty
|
* @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) {
|
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 (langs == null) {
|
||||||
if (countryCode != null) {
|
|
||||||
langs = new ArrayList<Locale>();
|
langs = new ArrayList<Locale>();
|
||||||
List<Locale> locales = availableLocaleList();
|
List<Locale> locales = availableLocaleList();
|
||||||
for (int i = 0; i < locales.size(); i++) {
|
for (int i = 0; i < locales.size(); i++) {
|
||||||
@ -276,10 +241,8 @@ public static List<Locale> languagesByCountry(String countryCode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
langs = Collections.unmodifiableList(langs);
|
langs = Collections.unmodifiableList(langs);
|
||||||
} else {
|
cLanguagesByCountry.putIfAbsent(countryCode, langs);
|
||||||
langs = Collections.emptyList();
|
langs = cLanguagesByCountry.get(countryCode);
|
||||||
}
|
|
||||||
cLanguagesByCountry.put(countryCode, langs); //syncd
|
|
||||||
}
|
}
|
||||||
return langs;
|
return langs;
|
||||||
}
|
}
|
||||||
@ -292,12 +255,14 @@ public static List<Locale> languagesByCountry(String countryCode) {
|
|||||||
* countries available for that language. Variant locales are removed.</p>
|
* countries available for that language. Variant locales are removed.</p>
|
||||||
*
|
*
|
||||||
* @param languageCode the 2 letter language code, null returns empty
|
* @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) {
|
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 (countries == null) {
|
||||||
if (languageCode != null) {
|
|
||||||
countries = new ArrayList<Locale>();
|
countries = new ArrayList<Locale>();
|
||||||
List<Locale> locales = availableLocaleList();
|
List<Locale> locales = availableLocaleList();
|
||||||
for (int i = 0; i < locales.size(); i++) {
|
for (int i = 0; i < locales.size(); i++) {
|
||||||
@ -309,12 +274,25 @@ public static List<Locale> countriesByLanguage(String languageCode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
countries = Collections.unmodifiableList(countries);
|
countries = Collections.unmodifiableList(countries);
|
||||||
} else {
|
cCountriesByLanguage.putIfAbsent(languageCode, countries);
|
||||||
countries = Collections.emptyList();
|
countries = cCountriesByLanguage.get(languageCode);
|
||||||
}
|
|
||||||
cCountriesByLanguage.put(languageCode, countries); //syncd
|
|
||||||
}
|
}
|
||||||
return countries;
|
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