This week's book giveaway is in the Performance forum.
We're giving away four copies of The Java Performance Companion and have Charlie Hunt, Monica Beckwith, Poonam Parhar, & Bengt Rutisson on-line!
See this thread for details.
Win a copy of The Java Performance Companion this week in the Performance forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Synchronization/Locking Question: Does this code really do anything?

 
Harry Henriques
Ranch Hand
Posts: 206
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Bloggers,

The following code block is intended to allow multiple threads to access the same HashMap simultaneously. The method employs a mechanism whereby individual Locks (values) are associated with individual Strings (keys). The idea is that one thread can hold the Lock (value) associated with one String (key), while another thread can hold the Lock associated with another String. Each thread can simultaneously "put" key-value pairs into the HashMap without any synchronization conflicts.

I think that this is false.

If a key-value pair isn't already in the HashMap, then one thread will acquire the Lock, and ithe Lock will actually block all access to the HashMap until the "put" operation is completed. No other thread will have access to the HashMap. There will not be any other simultaneous "put" operations on the HashMap, while one and only one thread holds a Lock.

Is this true, or is the designers objective implemented correctly?

Thanks,
Harry Henriques






 
Deepak Chopra
Ranch Hand
Posts: 433
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
you may want to use - ConcurrentHashMap<K, V>( ) as a thread safe HashMap.

Also in your code, you are making unnecessary checks- for example -



There are other redendency as well, you may try to find it out.
 
Harry Henriques
Ranch Hand
Posts: 206
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Sunny,

The attached code block was given to me as an example of a conservative and a necessary approach to the problem of multi-threading. In this example code, two different threads cannot "put" the same key-value pair into the "cache" HashMap at the same time. I was told that the multiple redundancies in this example were necessary, and in fact, that they are good practical coding. Isn't this true?

I was also told that while one thread has the lock, another thread with a different key-value pair can "put" this pair into the "cache" HashMap. This doesn't make any sense to me, either. While the bytecode is being used to "put" a key-value pair in the map with one thread, all access to that bytecode with other threads would be prevented. Two threads writing to the same HashMap at the same time would produce unpredicatble behavior, wouldn't it?

I agree with you. Doesn't ConcurrentHashMap prevent multiple threads from "putting" the same key-value pair into the map? Doesn't ConcurrentHashMap<K, V> or Hashtable exist for just this reason?

Thanks,
Harry Henriques
 
Nitesh Kant
Bartender
Posts: 1638
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sunny Jain wrote:There are other redendency as well, you may try to find it out.


This is an example of classic Double-checked_locking.

 
Nitesh Kant
Bartender
Posts: 1638
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Harry Henriques wrote:This doesn't make any sense to me, either. While the bytecode is being used to "put" a key-value pair in the map with one thread, all access to that bytecode with other threads would be prevented.


Not really true. Although, there is a part of the code (that creates a new lock instance) is a global lock for all threads, but the other part that actually puts an object in the hashmap uses different locks for different keys.

Harry Henriques wrote:Two threads writing to the same HashMap at the same time would produce unpredicatble behavior, wouldn't it?


Yes, it is not recommended to have two threads altering the structure of the HashMap at the same time.

Harry Henriques wrote:I agree with you. Doesn't ConcurrentHashMap prevent multiple threads from "putting" the same key-value pair into the map? Doesn't ConcurrentHashMap<K, V> or Hashtable exist for just this reason?


ConcurrentHashMap is not the same as HashTable. It allows you a higher concurrency than HashTable by having different segments (different hashmap inside the bigger map) and different locks for those segments.
In fact, I would consider this implementation to be a naive and incorrect attempt to have a concurrent HashMap.
 
Harry Henriques
Ranch Hand
Posts: 206
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you Nitesh,

I found the bibliography at the end of the Wikipedia article on double-checked locking you referenced to be very helpful.

Nitesh Kant wrote:In fact, I would consider this implementation to be a naive and incorrect attempt to have a concurrent HashMap.


I think that I understand the comment above. Are you saying that the example code, which I provided earlier, is a naive attempt to implement a concurrent HashMap? Would a better choice consist of using the ConcurrentHashMap container right from the start?

Thanks for the insights,
Harry Henriques
 
Nitesh Kant
Bartender
Posts: 1638
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Harry Henriques wrote:I found the bibliography at the end of the Wikipedia article on double-checked locking you referenced to be very helpful.

I am glad it helped.

Harry Henriques wrote:Are you saying that the example code, which I provided earlier, is a naive attempt to implement a concurrent HashMap?

Yes, indeed. What it is trying to do is concurrently allow multiple threads to use the HashMap which is what is the intent of ConcurrentHashMap. However, it is broken for various reasons.

Harry Henriques wrote:Would a better choice consist of using the ConcurrentHashMap container right from the start?

Absolutely, there is no reason to re-invent the wheel. One must use ConcurrentHashMap instead of writing something on their own.
 
Harry Henriques
Ranch Hand
Posts: 206
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Nitesh,

I'm far from expert on this topic, but something in the method, which I provided, didn't look quite right.

Nitesh Kant wrote:Yes, indeed. What it is trying to do is concurrently allow multiple threads to use the HashMap which is what is the intent of ConcurrentHashMap. However, it is broken for various reasons.


Do you have a moment to explain some of the various reasons that this method is broken?

Thanks,
Harry Henriques
 
Nitesh Kant
Bartender
Posts: 1638
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Harry Henriques wrote:Do you have a moment to explain some of the various reasons that this method is broken?


  • It allows multiple writes to the same HashMap concurrently, so, it is not thread-safe.
  • It does a global lock for each new entry, so, it does not scale for high number of puts with unique keys.
  • The number of locks is directly proportional to the number of elements which doubles the memory footprint for the map. This poses a lot of problems in operations where in some cases you have to resort to full map locking. (See ConcurrentHashMap for the cases)

  •  
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic