D'oh! I should have seen this. Thanks David

-Chris

David Holmes <david.hol...@oracle.com> wrote:

>Hi Chris,
>
>Thanks. Here's the bug:
>
>    private List<Locale> getJRELocales() {
>         if (availableJRELocales == null) {
>             synchronized (LocaleServiceProviderPool.class) {
>                 if (availableJRELocales == null) {
>                     Locale[] allLocales = LocaleData.getAvailableLocales();
>                     availableJRELocales = new 
>ArrayList<Locale>(allLocales.length); <<==== YIKES we just published an 
>empty ArrayList
>                     for (Locale locale : allLocales) {
>                         availableJRELocales.add(getLookupLocale(locale));
>                     }
>                 }
>             }
>         }
>         return availableJRELocales;
>     }
>
>
>availableJRELocales is a static variable shared across all pools. But it 
>is being published before it gets populated. We need to use a temporary 
>for the new ArrayList and only assign to availableJRELocales after it is 
>populated.
>
>In addition, as you mentioned, availableJRELocales needs to be volatile 
>for this DCL pattern to be correct.
>
>Thanks,
>David
>
>On 6/10/2011 9:02 PM, Chris Hegarty wrote:
>> I see several exceptions, similar to the following (numbers vary):
>>
>> Exception in thread "Thread-23"
>> java.util.ConcurrentModificationException: Expected: 96, got: 156
>> at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
>> at java.util.ArrayList$Itr.next(ArrayList.java:791)
>> at java.util.AbstractCollection.addAll(AbstractCollection.java:333)
>> at java.util.HashSet.<init>(HashSet.java:117)
>> at
>> sun.util.LocaleServiceProviderPool.getAvailableLocales(LocaleServiceProviderPool.java:206)
>>
>> at Interrupter$TestThread.run(Interrupter.java:49)
>
>
>>
>> There would appear to be 156 JRE Locales ( at least on this system ),
>> modCount is incremented for each add(), but when the iterator is created
>> ( implicitly during the HastSet.addAll ) it sees a different value for
>> modCount.
>>
>> I think there is a visibility issue here. availableJRELocales is
>> volatile, but the List reference returned from getJRELocales is not. In
>> the case where availableJRELocales is not null there will be no memory
>> barrier to force a HB relationship. Or maybe I've gotten this wrong? His
>> is quite bizarre, or maybe it is just the overly complicated use of
>> locking/DCL in this class.
>>
>> -Chris.
>>
>> On 10/ 5/11 07:01 PM, David Holmes wrote:
>>> This might not be related to the CME problem, but here:
>>>
>>> public static LocaleServiceProviderPool getPool(Class<? extends
>>> LocaleServiceProvider> providerClass) {
>>> LocaleServiceProviderPool pool = poolOfPools.get(providerClass);
>>> if (pool == null) {
>>> LocaleServiceProviderPool newPool =
>>> new LocaleServiceProviderPool(providerClass);
>>> pool = poolOfPools.put(providerClass, newPool);
>>> if (pool == null) {
>>> pool = newPool;
>>> }
>>> }
>>>
>>> return pool;
>>> }
>>>
>>> we should probably be using poolOfPools.putIfAbsent(providerClass,
>>> newPool)
>>>
>>> David
>>>
>>> On 6/10/2011 3:35 AM, Naoto Sato wrote:
>>>> I will look into this. Reopened the original CR.
>>>>
>>>> Naoto
>>>>
>>>> On 10/5/11 9:58 AM, Alan Bateman wrote:
>>>>> Chris Hegarty wrote:
>>>>>> Alan, Naoto, David
>>>>>>
>>>>>> I filed CR 7098100: java/util/Locale/Bug6989440.java fails
>>>>>> intermittently.
>>>>>>
>>>>>> If you're ok with it please review the patch (below) and I can push it
>>>>>> to the tl repo. Job done!
>>>>> I assume there is also some underlying issue in the Locale code and
>>>>> this
>>>>> might get hidden if we fix the test (I"ve no objection to fixing the
>>>>> test of course, just thinking that we should study the Locale code to
>>>>> try to identify the deadlock or hang or whatever it is that is causing
>>>>> the threads in this test not to terminate).
>>>>>
>>>>> -Alan
>>>>

Reply via email to