7027061: Testcase failure: java/util/Locale/Bug6989440.java - java.util.ConcurrentModificationException
Reviewed-by: dholmes, chegar
--- a/jdk/src/share/classes/sun/util/LocaleServiceProviderPool.java Wed Sep 28 15:10:02 2011 -0700
+++ b/jdk/src/share/classes/sun/util/LocaleServiceProviderPool.java Wed Oct 12 12:12:25 2011 -0700
@@ -40,6 +40,7 @@
import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.spi.LocaleServiceProvider;
import sun.util.logging.PlatformLogger;
@@ -57,8 +58,8 @@
* A Map that holds singleton instances of this class. Each instance holds a
* set of provider implementations of a particular locale sensitive service.
*/
- private static Map<Class, LocaleServiceProviderPool> poolOfPools =
- new ConcurrentHashMap<Class, LocaleServiceProviderPool>();
+ private static ConcurrentMap<Class, LocaleServiceProviderPool> poolOfPools =
+ new ConcurrentHashMap<>();
/**
* A Set containing locale service providers that implement the
@@ -109,7 +110,7 @@
if (pool == null) {
LocaleServiceProviderPool newPool =
new LocaleServiceProviderPool(providerClass);
- pool = poolOfPools.put(providerClass, newPool);
+ pool = poolOfPools.putIfAbsent(providerClass, newPool);
if (pool == null) {
pool = newPool;
}
@@ -257,10 +258,11 @@
synchronized (LocaleServiceProviderPool.class) {
if (availableJRELocales == null) {
Locale[] allLocales = LocaleData.getAvailableLocales();
- availableJRELocales = new ArrayList<Locale>(allLocales.length);
+ List<Locale> tmpList = new ArrayList<>(allLocales.length);
for (Locale locale : allLocales) {
- availableJRELocales.add(getLookupLocale(locale));
+ tmpList.add(getLookupLocale(locale));
}
+ availableJRELocales = tmpList;
}
}
}
--- a/jdk/test/java/util/Locale/Bug6989440.java Wed Sep 28 15:10:02 2011 -0700
+++ b/jdk/test/java/util/Locale/Bug6989440.java Wed Oct 12 12:12:25 2011 -0700
@@ -37,26 +37,49 @@
import sun.util.LocaleServiceProviderPool;
public class Bug6989440 {
- public static void main(String[] args) {
- TestThread t1 = new TestThread(LocaleNameProvider.class);
- TestThread t2 = new TestThread(TimeZoneNameProvider.class);
- TestThread t3 = new TestThread(DateFormatProvider.class);
+ static volatile boolean failed; // false
+ static final int THREADS = 50;
- t1.start();
- t2.start();
- t3.start();
+ public static void main(String[] args) throws Exception {
+ Thread[] threads = new Thread[THREADS];
+ for (int i=0; i<threads.length; i++)
+ threads[i] = new TestThread();
+ for (int i=0; i<threads.length; i++)
+ threads[i].start();
+ for (int i=0; i<threads.length; i++)
+ threads[i].join();
+
+ if (failed)
+ throw new RuntimeException("Failed: check output");
}
static class TestThread extends Thread {
private Class<? extends LocaleServiceProvider> cls;
+ private static int count;
public TestThread(Class<? extends LocaleServiceProvider> providerClass) {
cls = providerClass;
}
+ public TestThread() {
+ int which = count++ % 3;
+ switch (which) {
+ case 0 : cls = LocaleNameProvider.class; break;
+ case 1 : cls = TimeZoneNameProvider.class; break;
+ case 2 : cls = DateFormatProvider.class; break;
+ default : throw new AssertionError("Should not reach here");
+ }
+ }
+
public void run() {
- LocaleServiceProviderPool pool = LocaleServiceProviderPool.getPool(cls);
- pool.getAvailableLocales();
+ try {
+ LocaleServiceProviderPool pool = LocaleServiceProviderPool.getPool(cls);
+ pool.getAvailableLocales();
+ } catch (Exception e) {
+ System.out.println(e);
+ e.printStackTrace();
+ failed = true;
+ }
}
}
}