mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-21 12:40:02 +00:00
ICU-2787 double-checked locking fixes
X-SVN-Rev: 11807
This commit is contained in:
parent
725e9155d0
commit
8554a06031
7 changed files with 104 additions and 125 deletions
|
@ -5,8 +5,8 @@
|
|||
*******************************************************************************
|
||||
*
|
||||
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/impl/ICUService.java,v $
|
||||
* $Date: 2003/02/05 05:45:16 $
|
||||
* $Revision: 1.15 $
|
||||
* $Date: 2003/05/05 23:42:18 $
|
||||
* $Revision: 1.16 $
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
@ -98,6 +98,9 @@ import java.util.TreeMap;
|
|||
* resource bundle fallback strategy.<p>
|
||||
*/
|
||||
public class ICUService extends ICUNotifier {
|
||||
/**
|
||||
* Name used for debugging.
|
||||
*/
|
||||
protected final String name;
|
||||
|
||||
/**
|
||||
|
@ -126,6 +129,12 @@ public class ICUService extends ICUNotifier {
|
|||
*/
|
||||
private final List factories = new ArrayList();
|
||||
|
||||
/**
|
||||
* Record the default number of factories for this service.
|
||||
* Can be set by markDefault.
|
||||
*/
|
||||
private int defaultSize = 0;
|
||||
|
||||
/**
|
||||
* Keys are used to communicate with factories to generate an
|
||||
* instance of the service. Keys define how ids are
|
||||
|
@ -869,7 +878,15 @@ public class ICUService extends ICUNotifier {
|
|||
* implementation returns true if there are no factories registered.
|
||||
*/
|
||||
public boolean isDefault() {
|
||||
return factories.size() == 0;
|
||||
return factories.size() == defaultSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default size to the current number of registered factories.
|
||||
* Used by subclasses to customize the behavior of isDefault.
|
||||
*/
|
||||
protected void markDefault() {
|
||||
defaultSize = factories.size();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
*******************************************************************************
|
||||
*
|
||||
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/BreakIterator.java,v $
|
||||
* $Date: 2003/02/15 00:29:03 $
|
||||
* $Revision: 1.16 $
|
||||
* $Date: 2003/05/05 23:42:17 $
|
||||
* $Revision: 1.17 $
|
||||
*
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
@ -568,10 +568,10 @@ public abstract class BreakIterator implements Cloneable
|
|||
* @draft ICU 2.4
|
||||
*/
|
||||
public static boolean unregister(Object key) {
|
||||
if (shim == null) {
|
||||
return false;
|
||||
if (hasShim()) {
|
||||
return shim.unregister(key);
|
||||
}
|
||||
return shim.unregister(key);
|
||||
return false;
|
||||
}
|
||||
|
||||
// end of registration
|
||||
|
@ -634,22 +634,30 @@ public abstract class BreakIterator implements Cloneable
|
|||
}
|
||||
|
||||
private static BreakIteratorServiceShim shim;
|
||||
private static boolean hasShim() {
|
||||
synchronized(BreakIterator.class) {
|
||||
return shim != null;
|
||||
}
|
||||
}
|
||||
|
||||
private static BreakIteratorServiceShim getShim() {
|
||||
BreakIteratorServiceShim newshim = null;
|
||||
if (shim == null) {
|
||||
try {
|
||||
Class cls = Class.forName("com.ibm.icu.text.BreakIteratorFactory");
|
||||
BreakIteratorServiceShim newshim = (BreakIteratorServiceShim)cls.newInstance();
|
||||
synchronized(BreakIterator.class) {
|
||||
if (shim == null) {
|
||||
shim = newshim;
|
||||
}
|
||||
}
|
||||
newshim = (BreakIteratorServiceShim)cls.newInstance();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
synchronized(BreakIterator.class) {
|
||||
if (shim == null) {
|
||||
shim = newshim;
|
||||
}
|
||||
}
|
||||
return shim;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
*******************************************************************************
|
||||
*
|
||||
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/BreakIteratorFactory.java,v $
|
||||
* $Date: 2003/02/15 00:29:04 $
|
||||
* $Revision: 1.2 $
|
||||
* $Date: 2003/05/05 23:42:17 $
|
||||
* $Revision: 1.3 $
|
||||
*
|
||||
*****************************************************************************************
|
||||
*/
|
||||
|
@ -39,14 +39,14 @@ import com.ibm.icu.impl.LocaleUtility;
|
|||
final class BreakIteratorFactory extends BreakIterator.BreakIteratorServiceShim {
|
||||
|
||||
public Object registerInstance(BreakIterator iter, Locale locale, int kind) {
|
||||
return getService().registerObject(iter, locale, kind);
|
||||
return service.registerObject(iter, locale, kind);
|
||||
}
|
||||
|
||||
public boolean unregister(Object key) {
|
||||
if (service != null) {
|
||||
return service.unregisterFactory((Factory)key);
|
||||
if (service.isDefault()) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
return service.unregisterFactory((Factory)key);
|
||||
}
|
||||
|
||||
public Locale[] getAvailableLocales() {
|
||||
|
@ -58,33 +58,27 @@ final class BreakIteratorFactory extends BreakIterator.BreakIteratorServiceShim
|
|||
}
|
||||
|
||||
public BreakIterator createBreakIterator(Locale locale, int kind) {
|
||||
if (service == null) {
|
||||
if (service.isDefault()) {
|
||||
return createBreakInstance(locale, kind);
|
||||
}
|
||||
return (BreakIterator)service.get(locale, kind);
|
||||
}
|
||||
|
||||
private ICULocaleService service;
|
||||
private ICULocaleService getService() {
|
||||
if (service == null) {
|
||||
ICULocaleService newService = new ICULocaleService("BreakIterator");
|
||||
private static class BFService extends ICULocaleService {
|
||||
BFService() {
|
||||
super("BreakIterator");
|
||||
|
||||
class RBBreakIteratorFactory extends ICUResourceBundleFactory {
|
||||
protected Object handleCreate(Locale loc, int kind, ICUService service) {
|
||||
return createBreakInstance(loc, kind);
|
||||
}
|
||||
}
|
||||
newService.registerFactory(new RBBreakIteratorFactory());
|
||||
registerFactory(new RBBreakIteratorFactory());
|
||||
|
||||
synchronized (this) {
|
||||
if (service == null) {
|
||||
service = newService;
|
||||
}
|
||||
}
|
||||
markDefault();
|
||||
}
|
||||
return service;
|
||||
}
|
||||
|
||||
static final ICULocaleService service = new BFService();
|
||||
|
||||
private static final String[] KIND_NAMES = {
|
||||
"Character", "Word", "Line", "Sentence", "Title"
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
*******************************************************************************
|
||||
*
|
||||
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/CollatorServiceShim.java,v $
|
||||
* $Date: 2003/04/19 00:01:53 $
|
||||
* $Revision: 1.1 $
|
||||
* $Date: 2003/05/05 23:42:17 $
|
||||
* $Revision: 1.2 $
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
@ -30,7 +30,7 @@ import com.ibm.icu.text.Collator.CollatorFactory;
|
|||
final class CollatorServiceShim extends Collator.ServiceShim {
|
||||
|
||||
Collator getInstance(Locale locale) {
|
||||
if (service == null) {
|
||||
if (service.isDefault()) {
|
||||
return new RuleBasedCollator(locale);
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ final class CollatorServiceShim extends Collator.ServiceShim {
|
|||
}
|
||||
|
||||
Object registerInstance(Collator collator, Locale locale) {
|
||||
return getService().registerObject(collator, locale);
|
||||
return service.registerObject(collator, locale);
|
||||
}
|
||||
|
||||
Object registerFactory(CollatorFactory f) {
|
||||
|
@ -73,18 +73,15 @@ final class CollatorServiceShim extends Collator.ServiceShim {
|
|||
}
|
||||
}
|
||||
|
||||
return getService().registerFactory(new CFactory(f));
|
||||
return service.registerFactory(new CFactory(f));
|
||||
}
|
||||
|
||||
boolean unregister(Object registryKey) {
|
||||
if (service == null) {
|
||||
return false;
|
||||
}
|
||||
return service.unregisterFactory((Factory)registryKey);
|
||||
}
|
||||
|
||||
Locale[] getAvailableLocales() {
|
||||
if (service == null) {
|
||||
if (service.isDefault()) {
|
||||
return ICULocaleData.getAvailableLocales();
|
||||
}
|
||||
return service.getAvailableLocales();
|
||||
|
@ -92,25 +89,17 @@ final class CollatorServiceShim extends Collator.ServiceShim {
|
|||
|
||||
Map getDisplayNames(Locale locale) {
|
||||
Collator col = Collator.getInstance(locale);
|
||||
return getService().getDisplayNames(locale, col, null);
|
||||
return service.getDisplayNames(locale, col, null);
|
||||
}
|
||||
|
||||
String getDisplayName(Locale objectLocale, Locale displayLocale) {
|
||||
String id = LocaleUtility.canonicalLocaleString(objectLocale);
|
||||
return getService().getDisplayName(id, displayLocale);
|
||||
return service.getDisplayName(id, displayLocale);
|
||||
}
|
||||
|
||||
private static ICULocaleService service;
|
||||
private static ICULocaleService getService() {
|
||||
if (service == null) {
|
||||
ICULocaleService newService = new ICULocaleService("Collator") {
|
||||
protected Object handleDefault(Key key, String[] actualIDReturn) {
|
||||
if (actualIDReturn != null) {
|
||||
actualIDReturn[0] = "root";
|
||||
}
|
||||
return new RuleBasedCollator(new Locale("", "", ""));
|
||||
}
|
||||
};
|
||||
private static class CService extends ICULocaleService {
|
||||
CService() {
|
||||
super("Collator");
|
||||
|
||||
class CollatorFactory extends ICUResourceBundleFactory {
|
||||
protected Object handleCreate(Locale loc, int kind, ICUService service) {
|
||||
|
@ -121,14 +110,17 @@ final class CollatorServiceShim extends Collator.ServiceShim {
|
|||
return ICULocaleData.getAvailableLocaleNameSet();
|
||||
}
|
||||
}
|
||||
newService.registerFactory(new CollatorFactory());
|
||||
|
||||
synchronized (Collator.class) {
|
||||
if (service == null) {
|
||||
service = newService;
|
||||
}
|
||||
}
|
||||
registerFactory(new CollatorFactory());
|
||||
markDefault();
|
||||
}
|
||||
|
||||
protected Object handleDefault(Key key, String[] actualIDReturn) {
|
||||
if (actualIDReturn != null) {
|
||||
actualIDReturn[0] = "root";
|
||||
}
|
||||
return new RuleBasedCollator(new Locale("", "", ""));
|
||||
}
|
||||
return service;
|
||||
}
|
||||
private static ICULocaleService service = new CService();
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
*******************************************************************************
|
||||
*
|
||||
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/NumberFormatServiceShim.java,v $
|
||||
* $Date: 2003/02/25 23:39:44 $
|
||||
* $Revision: 1.1 $
|
||||
* $Date: 2003/05/05 23:42:17 $
|
||||
* $Revision: 1.2 $
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
@ -30,11 +30,10 @@ import com.ibm.icu.text.NumberFormat.NumberFormatFactory;
|
|||
class NumberFormatServiceShim extends NumberFormat.NumberFormatShim {
|
||||
|
||||
Locale[] getAvailableLocales() {
|
||||
if (service == null) {
|
||||
if (service.isDefault()) {
|
||||
return ICULocaleData.getAvailableLocales();
|
||||
} else {
|
||||
return service.getAvailableLocales();
|
||||
}
|
||||
return service.getAvailableLocales();
|
||||
}
|
||||
|
||||
private static final class NFFactory extends LocaleKeyFactory {
|
||||
|
@ -67,43 +66,33 @@ class NumberFormatServiceShim extends NumberFormat.NumberFormatShim {
|
|||
}
|
||||
|
||||
Object registerFactory(NumberFormatFactory factory) {
|
||||
return getService().registerFactory(new NFFactory(factory));
|
||||
return service.registerFactory(new NFFactory(factory));
|
||||
}
|
||||
|
||||
boolean unregister(Object registryKey) {
|
||||
if (service == null) {
|
||||
return false;
|
||||
} else {
|
||||
return service.unregisterFactory((Factory)registryKey);
|
||||
}
|
||||
return service.unregisterFactory((Factory)registryKey);
|
||||
}
|
||||
|
||||
NumberFormat createInstance(Locale desiredLocale, int choice) {
|
||||
if (service == null) {
|
||||
if (service.isDefault()) {
|
||||
return NumberFormat.createInstance(desiredLocale, choice);
|
||||
}
|
||||
NumberFormat result = (NumberFormat)service.get(desiredLocale, choice);
|
||||
return (NumberFormat)result.clone();
|
||||
return (NumberFormat)service.get(desiredLocale, choice);
|
||||
}
|
||||
|
||||
private ICULocaleService service = null;
|
||||
private ICULocaleService getService() {
|
||||
if (service == null) {
|
||||
private static class NFService extends ICULocaleService {
|
||||
NFService() {
|
||||
super("NumberFormat");
|
||||
|
||||
class RBNumberFormatFactory extends ICUResourceBundleFactory {
|
||||
protected Object handleCreate(Locale loc, int kind, ICUService service) {
|
||||
return NumberFormat.createInstance(loc, kind);
|
||||
}
|
||||
}
|
||||
|
||||
ICULocaleService newService = new ICULocaleService("NumberFormat");
|
||||
newService.registerFactory(new RBNumberFormatFactory());
|
||||
|
||||
synchronized (NumberFormatServiceShim.class) {
|
||||
if (service == null) {
|
||||
service = newService;
|
||||
}
|
||||
}
|
||||
registerFactory(new RBNumberFormatFactory());
|
||||
markDefault();
|
||||
}
|
||||
return service;
|
||||
}
|
||||
private ICULocaleService service = new NFService();
|
||||
}
|
||||
|
|
|
@ -1692,20 +1692,9 @@ public abstract class Calendar implements Serializable, Cloneable {
|
|||
|
||||
private static ICULocaleService service = null;
|
||||
private static ICULocaleService getService() {
|
||||
if (service == null) {
|
||||
ICULocaleService newService = new ICULocaleService("Calendar");
|
||||
/*
|
||||
class RBCalendarFactory extends ICUResourceBundleFactory {
|
||||
protected Object handleCreate(Locale locale, int kind, ICUService service) {
|
||||
return GregorianCalendar.factory();
|
||||
}
|
||||
}
|
||||
newService.registerFactory(new RBCalendarFactory());
|
||||
*/
|
||||
synchronized (Calendar.class) {
|
||||
if (service == null) {
|
||||
service = newService;
|
||||
}
|
||||
synchronized (Calendar.class) {
|
||||
if (service == null) {
|
||||
service = new ICULocaleService("Calendar");
|
||||
}
|
||||
}
|
||||
return service;
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
*******************************************************************************
|
||||
*
|
||||
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/util/CurrencyServiceShim.java,v $
|
||||
* $Date: 2003/04/21 21:02:42 $
|
||||
* $Revision: 1.1 $
|
||||
* $Date: 2003/05/05 23:42:18 $
|
||||
* $Revision: 1.2 $
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
@ -31,36 +31,30 @@ import com.ibm.icu.impl.ICULocaleService.ICUResourceBundleFactory;
|
|||
final class CurrencyServiceShim extends Currency.ServiceShim {
|
||||
|
||||
Locale[] getAvailableLocales() {
|
||||
if (service == null) {
|
||||
if (service.isDefault()) {
|
||||
return ICULocaleData.getAvailableLocales();
|
||||
} else {
|
||||
return service.getAvailableLocales();
|
||||
}
|
||||
return service.getAvailableLocales();
|
||||
}
|
||||
|
||||
Currency createInstance(Locale loc) {
|
||||
if (service == null) {
|
||||
if (service.isDefault()) {
|
||||
return Currency.createCurrency(loc);
|
||||
} else {
|
||||
return (Currency)service.get(loc);
|
||||
}
|
||||
return (Currency)service.get(loc);
|
||||
}
|
||||
|
||||
Object registerInstance(Currency currency, Locale locale) {
|
||||
return getService().registerObject(currency, locale);
|
||||
return service.registerObject(currency, locale);
|
||||
}
|
||||
|
||||
boolean unregister(Object registryKey) {
|
||||
if (service == null) {
|
||||
return false;
|
||||
}
|
||||
return service.unregisterFactory((Factory)registryKey);
|
||||
}
|
||||
|
||||
private static ICULocaleService service;
|
||||
private static ICULocaleService getService() {
|
||||
if (service == null) {
|
||||
ICULocaleService newService = new ICULocaleService("Currency");
|
||||
private static class CFService extends ICULocaleService {
|
||||
CFService() {
|
||||
super("Currency");
|
||||
|
||||
class CurrencyFactory extends ICUResourceBundleFactory {
|
||||
protected Object handleCreate(Locale loc, int kind, ICUService service) {
|
||||
|
@ -68,13 +62,9 @@ final class CurrencyServiceShim extends Currency.ServiceShim {
|
|||
}
|
||||
}
|
||||
|
||||
newService.registerFactory(new CurrencyFactory());
|
||||
synchronized (CurrencyServiceShim.class) {
|
||||
if (service == null) {
|
||||
service = newService;
|
||||
}
|
||||
}
|
||||
registerFactory(new CurrencyFactory());
|
||||
markDefault();
|
||||
}
|
||||
return service;
|
||||
}
|
||||
static final ICULocaleService service = new CFService();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue