[concurrency-interest] Initializing a map inside a constructor

Brian Goetz brian at quiotix.com
Mon Mar 5 14:45:43 EST 2007


The initialization safety guarantee offered by the new Java Memory Model 
guarantees that any value set in a constructor that is reached through a 
final field is guaranteed to be visible to any thread that loads a 
reference to the enclosing object.  Without the 'final', it is a 
garden-variety data race.

If the Foo object is properly published, you're OK with or without the 
final modifier, since m is effectively immutable.  If m is final, it is 
safe whether or not Foo is properly published.

Robert Konigsberg 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 <mailto: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
>     <mailto:Concurrency-interest at altair.cs.oswego.edu>
>     http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
> 
> 
> 
> 
> -- 
> Robert Konigsberg
> konigsberg at gmail.com <mailto: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