[concurrency-interest] any read guarantees for static finals?

Vitaly Davidovich vitalyd at gmail.com
Thu Feb 9 15:13:08 EST 2012


I agree that it's not clearly spelled out in terms of HB and JMM (unless I
missed it).  However, I don't see how java would work if it didn't provide
this guarantee given what static means in java.  If two threads
(unknowingly) race to initialize the class (not much you can do about that
in practical terms as a developer) and then try to read a statically
initialized field, it shouldn't matter which thread actually came "first" -
they shouldn't see different values based on that or else the whole notion
of static is messed up.

Sent from my phone
On Feb 9, 2012 2:16 PM, "Yuval Shavit" <yshavit at akiban.com> wrote:

> Is it generally valid to make visibility assumptions on the JVM spec? I've
> always been going by the JLS, which from what I understand is a bit looser
> in its guarantees.
>
> JLS 12.4.2 does talk about class initialization in detail, and also
> mentions a lock such that only one thread is allowed to init the class.
> That said, if the class is already initialized, I don't see anything in the
> spec that requires such a lock -- the details of answering "is this class
> already initialized?" seems to be unspecified. So, it seems that if thread
> A initializes the class, and some time later thread B uses the class for
> the first time, there's nothing requiring thread B to try to initialize the
> class, meaning there's no synchronization and no HB. Indeed, without that
> behavior, every thread would be forced to acquire a lock at least once for
> every class it sees, which would seem prohibitive.
>
> On Thu, Feb 9, 2012 at 1:42 PM, Vitaly Davidovich <vitalyd at gmail.com>wrote:
>
>> JVM spec 2.17.5 talks about static initialization in a bit of detail.  It
>> doesn't explicitly mention memory visibility but it does make it clear that
>> a lock/unlock is associated with initialization such that only 1 thread is
>> allowed to init the class.  I think this implies that initializing writes
>> will be visible.
>>
>> Sent from my phone
>> On Feb 9, 2012 1:27 PM, "Yuval Shavit" <yshavit at akiban.com> wrote:
>>
>>> Where is that in the JLS? I can't find it (I'm looking especially
>>> at 17.4.5, "Happens-before Order").
>>>
>>> On Thu, Feb 9, 2012 at 12:48 PM, Vitaly Davidovich <vitalyd at gmail.com>wrote:
>>>
>>>> Static initialization guarantees visibility, so even without final on
>>>> the map it's guaranteed that all static initializing writes are seen across
>>>> cores (obviously subsequent writes to non-final non-volatile static fields
>>>> aren't guaranteed to be visible).
>>>>
>>>> Sent from my phone
>>>> On Feb 9, 2012 12:32 PM, "Yuval Shavit" <yshavit at akiban.com> wrote:
>>>>
>>>>> I've wondered this for a bit, and it finally came up in a
>>>>> stackoverflow discussion recently. The JLS's description of final field
>>>>> read semantics (as far as all threads seeing the state at least as it was
>>>>> at the end of the constructor) only seems to apply to member fields -- not
>>>>> statics. Specifically, JLS 17,5 refers only to object construction, not
>>>>> class instantiation. JLS 13.4.9 states that primitives and Strings have to
>>>>> be seen initialized, but makes no reference to other fields. So, are there
>>>>> actually any guarantees for static finals?
>>>>>
>>>>> For instance, is this class thread-safe, given that it uses a
>>>>> non-thread-safe map which is initialized statically and then never modified?
>>>>>
>>>>>     import java.util.*;
>>>>>     public class PoorMansEnum {
>>>>>         private static final Map<String,Integer> map = createMap();
>>>>>
>>>>>         private static Map<String,Integer> createMap() {
>>>>>             Map<String,Integer> map = new HashMap<String,Integer>();
>>>>>             map.put("Foo", 1);
>>>>>             map.put("Bar", 2);
>>>>>             return map;
>>>>>         }
>>>>>
>>>>>         public static int valueOf(String value) {
>>>>>             Integer integer = map.get(value);
>>>>>             if (integer == null)
>>>>>                 throw new IllegalArgumentException("not a value: " +
>>>>> value);
>>>>>             return integer;
>>>>>         }
>>>>>     }
>>>>>
>>>>> Is there even a guarantee that every thread will see a non-null "map"?
>>>>> I can't find anything in the JLS about it.
>>>>>
>>>>> Thanks,
>>>>> -Yuval
>>>>>
>>>>> _______________________________________________
>>>>> Concurrency-interest mailing list
>>>>> Concurrency-interest at cs.oswego.edu
>>>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>>>>
>>>>>
>>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20120209/2793efd3/attachment-0001.html>


More information about the Concurrency-interest mailing list