[concurrency-interest] synchronized maps

David Holmes dcholmes at optusnet.com.au
Mon Aug 27 00:25:33 EDT 2007


Dhanji,

Once an entry (K, V1) is in the map (CHM) then the difference between put(K,
V2) and putIfAbsent(K, V2) is negligible - a single extra putField in the
put() case. In CHM the two methods share the exact same code - with a flag
controlling whether or not a replacing store takes place.

The get() method for CHM does not use locking except in a very rare
(theoretical but not observed in practice) case.

java.util.HashMap is safe for concurrent reads as long as no structural
modifications occur concurrently. If you publish via a final field of
another object, then as long as you didn't publish that object during
construction, the assignment to the final field must happen-before any
susequent read of the final field. Hence any modifications to the map must
happen-before any subsequents reads of the map.

Cheers,
David Holmes
  -----Original Message-----
  From: concurrency-interest-bounces at cs.oswego.edu
[mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of Dhanji R.
Prasanna
  Sent: Monday, 27 August 2007 1:14 PM
  To: concurrency-interest
  Subject: [concurrency-interest] synchronized maps


  Hi,

  I have a JIT-style cache implemented as a HashMap. When client code
requests a key, it looks for an entry and if there is nothing, "compiles"
and stashes a value for that key. Currently, I am using a
Collections.synchronizedMap () wrapper over a j.u.HM. Since I am assured
that the value for a key ("natural value") is always the same, I don't
really care if multiple threads compile and overwrite the same key
concurrently.

  Am I correct in assuming that using a ConcurrentMap.putIfAbsent() will be
faster in my case (so I can discard concurrently compiled values that are
"later" than the first-put) than a straightforward synchronized overwrite
(multiple puts)?

  Assuming of course, that the cost of creating the value is negligible
compared to the cost of locking the entire cache-get method as number of
threads increase... the cache-get method exposed to client code right now is
(deliberately) unsynchronized.


  I have another minor question regarding j.u.HM. I publish an unmodifiable
(pre-constructed) HM instance to a final member of an object, is it safe to
assume that leaving the map unsynchronized for multiple threads invoking
get() is ok ( i.e. is there any kind of internal optimization after the
last-put)?

  Thanks in advance,

  Dhanji.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: /pipermail/attachments/20070827/d87ce768/attachment.html 


More information about the Concurrency-interest mailing list