ICU-2787 double-checked locking fixes

X-SVN-Rev: 11807
This commit is contained in:
Doug Felt 2003-05-05 23:42:18 +00:00
parent 725e9155d0
commit 8554a06031
7 changed files with 104 additions and 125 deletions

View file

@ -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();
}
/**

View file

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

View file

@ -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"

View file

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

View file

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

View file

@ -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;

View file

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