• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

proper synchronization in HashMap

 
Yan Zhou
Ranch Hand
Posts: 137
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Suppose in my class, it has a data member:

private Map myObjs = Collections.synchronizedMap(new HashMap());

I then have a number of member functions that adds/removes/reads/iterates through this map.

In addition to use Collections.synchronizedMap() to ensure the collection itself is thread-safe. I think it would be necessary to declare all methods that change/iterates through the map to be synchronized, too. However, any functions that read from the map does NOT need to be synchronized since the collection itself is thread-safe.

Is this two level of synchornization appropriate?
Thanks.
Yan
 
Kai Witte
Ranch Hand
Posts: 356
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hello,
Originally posted by Yan Zhou:

Is this two level of synchornization appropriate?

depends.

Example where you don't need extra synchronization:
An element of the Map has to be removed. It does not hurt when two threads remove it, although one of them will get null as return value of remove.

An other example where you don't need extra synchronization:
You want to iterate over the Map. Several threads can access this Map, but with your program logic you made sure that none of them tries while you iterate over it.

An example where you need extra synchronization:
You need the map to map store locks in a lock method, like in the SCJD assignment. Let IntegerPool.getInstance().getInteger(recNo) be a way to retrieve an Integer that wraps the int recNo and that is guaranteed to be reused (simplified). Here an extra synchronization makes sense, like this:

The extra synchronization here makes sure that really only one client can obtain a lock for the same record at the same time. Otherwise this could happen, although you use a synchronized Map:
  • Thread 1 checks if the Integer is in the map, and it isn't
  • Thread 2 checks if the Integer is in the map, and it isn't
  • Thread 1 puts it there
  • Thread 2 puts it there

  • And in this case you still need the kind of synchronization you can get for example with Collections.synchronizedMap, because otherwise you would have to synchronize always on the same Integer when working with the map. So you would really need both synchronizations in this case.

    So briefly: It depends.

    Conan
     
    Kai Witte
    Ranch Hand
    Posts: 356
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    p. s.: "extra synchronization" means additionally to the one you get with Collections.synchronizedMap.

    Conan
     
    Inuka Vincit
    Ranch Hand
    Posts: 175
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I thought you baught up a good point that I didnt think about in my design.. and I was looking around came across an article that I thought was usefull.

    http://www-106.ibm.com/developerworks/java/library/j-jtp07233.html

    Depend on how your using the Map. Like Conan said it seems neccary if your storing locks. However in my case I am using the container as cache and locking on the actual record, in which case the locking mechanisms deal with deadlocks except in the case of the Createmethod which I chose to add two levels of sychronization on. I may have missed something here so please point anything out if that is the case .
     
    Kai Witte
    Ranch Hand
    Posts: 356
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    hello Inuka,

    synchronizing on an identifier for the record number only is not enough when you use the HashMap implementation. A HashMap is allowed to do very strange things when you access it with several threads and don't synchronize on the same object each time!

    or better:

    But in this case a synchronized Map looks better because of the nested synchronized blocks. Don't get confused: The synchronized blocks have very different purposes! One is required for the logic you described and one is to respect the HashMap documentation about how to make it thread-safe!

    It may seem like it is enough to synchronize on an identifier for a specific record as long as you deal only with this key of the map inside the block. But when you do that the HashMap is allowed to do basically whatever it wants! It might return a kangaroo all of a sudden or transform itself into a green, illuminating egg!

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