[concurrency-interest] Initializing a map inside a constructor

Brian Goetz brian at quiotix.com
Mon Mar 5 15:23:14 EST 2007


In the absence of final fields, there's nothing special about the end of 
a constructor.

In the presence of final fields, the end of a constructor is special, 
and offers something like the effects of releasing a lock, but only for 
the state reachable through that objects final fields.

Howard Lewis Ship wrote:
> I kind of interpreted this as: the JVM "flushes out" changes at the
> end of the constructor, much as it would at the end of a synchronized
> block.
> 
> On 3/5/07, Robert Konigsberg <konigsberg at gmail.com> wrote:
>> I'm not sure I follow you. How is m not effectively immutable? I presume
>> that 'no other modifications to 'm'' refers to both to reassigning the
>> reference as well as mutating the contents.
>>
>> It's also my assumption that any difference in compiler optimizations
>> between your two examples are effectively irrelevant. Is it possible that
>> I'm wrong about that?
>>
>> Thanks, Robert
>>
>> On 3/5/07, Brian Goetz <brian at quiotix.com> wrote:
>>> This code is thread-safe:
>>>
>>> public class Foo {
>>>      private final Map m = new HashMap();
>>>
>>>      public Foo() {
>>>          m.put("foo", "bar");
>>>      }
>>>
>>>      public isKnown(String s) {
>>>          return m.containsKey(s);
>>>      }
>>>
>>>      // no other modification to m
>>> }
>>>
>>> and this code is not:
>>>
>>> public class Foo {
>>>      private Map m = new HashMap();
>>>
>>>      public Foo() {
>>>          m.put("foo", "bar");
>>>      }
>>>
>>>      public isKnown(String s) {
>>>          return m.containsKey(s);
>>>      }
>>>
>>>      // no other modification to m
>>> }
>>>
>>> The difference is the final keyword.  If the map is effectively
>>> immutable, and the reference to it is final, and the values are set in
>>> the constructor, and the 'this' reference doesn't escape construction,
>>> you're OK.
>>>
>>> Howard Lewis Ship wrote:
>>>> I'm seeing some very strange effects in my code under load.  I've been
>>>> reviewing Brian Goetz's concurrency book, but I have a scenario I
>>>> frequently use that I have come to suspect:
>>>>
>>>> I often have classes with a final field of type Map.
>>>>
>>>> I initialize the Map, loading values inside the constructor.  I never
>>>> change the contents
>>>> of the Map outside of the constructor.
>>>>
>>>> I don't use a guard (i.e. synchronized) to access the map from other
>> code.
>>>> Is this thread safe, or do I need to synchronize the methods (or wrap
>>>> the map in a synchronzing wrapper)?
>>>>
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> Concurrency-interest at altair.cs.oswego.edu
>>>
>> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
>> --
>> Robert Konigsberg
>> konigsberg at gmail.com
>>
>> "... you know what they say: Fool me once, shame on you. Fool me twice,
>> shame on The Cheat."
> 
> 


More information about the Concurrency-interest mailing list