Question: I have gone through the below links
[Problem with synchronizing on String objects?](https://stackoverflow.com/questions/133988/problem-with-synchronizing-on-string-objects)
and
<http://illegalargumentexception.blogspot.com/2008/04/java-synchronizing-on-transient-id.html>

Now my question:

1. I have a map where userid and a list of some properties are maintained
2. when we come across new userid we will create an entry in the map
3. if the userid is already present we will add some properties to the value

instead of synchronizing on the whole map, we tried to synchronize on the userid and that results in some random behavior, if we use intern() it works
the approach in the second link also works

Questions:

1. in the second approach we are still locking the whole map when getting key
2. is there some other way of synchronization so that the map access is synchronized based on userid alone
3. what is the best way to do this?

Answer: 
The best way is to use a [ConcurrentHashMap](http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html) from the [java.util.concurrent package](http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/package-summary.html). This class has everything you need built right in. Don't re-invent the wheel!

Note: Thilo is right: You must use ConcurrentHashMap's special thread-safe version of put: [putIfAbsent()](http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html#putIfAbsent%28K,%20V%29)
Use a `ConcurrentMap<String, UserProperties>`.

The code to get the appropriate `UserProperties` would look like this:

```
public UserProperties getProperties(String user) {
    UserProperties newProperties = new UserProperties();
    UserProperties alreadyStoredProperties = map.putIfAbsent(user, newProperties);
    if (alreadyStoredProperties != null) {
        return alreadyStoredProperties;
    }
    else {
        return newProperties;
    }
}

```