The high-level explanation of how Doug Lea's ConcurrentHashMap works is that it has 32 internal buckets and a fast hashing algorithm. It only synchronizes internally on the bucket that is being modified, thereby leaving the other n buckets free to do whatever they need. So you can conceivably have 32 concurrent threads reading and/or writing depending on how the hashing algorithm causes the buckets to be synchronized.
It's a lot faster than a java.util.HashMap when you have many threads reading and writing.
I think the 32 fixed bucket size limit was removed when these classes were ported to JDK 1.5.
Depending on what you are doing, you basically have 3 choices when you're dealing with multithreaded access/modification to a collection:
1) don't synchronize and watch failures happen
2) synchronize on the containing object's monitor:
... public synchronized whatever(Object arg1) {...} public synchronized something() {...} ...
3) use more granular synch locks, if possible:
... private Object whatever = new Object(); private Object something = new Object();
public whatever(Object arg1) { synchronized (whatever) { ... } }
public something(Object arg1) { synchronized (something) { ... } }
Making the locks more granular can make a huge difference, but it's only possible if your particular case will allow for it. But it's definitely worth investigating rather than blindly using 'synchronized' in method signatures... which turns out to be not-that-slow anyway.
YMMV.
phil.
[1] http://whirlycache.dev.java.net/
Torsten Curdt wrote:
Guys, forgive me if this too off topic...
...but I thought it is somehow related to collections that's why I am bringing it up here anyway. I bet someone of you will know....
Consider this code...
Object o = map.get(key); if (o == null) { synchronized(map) { map.put(key,new Object()); } }
99% of the time the "get"s on the map are going to return an object. That's why I would like to avoid synchronizing the "get" access. Now since a "put" might corrupt the data it has to be synchronized.
Since the "get", the comparison and the "put" are not in a synchronized block I might loose objects ...but for this particular usecase that's ok.
Now what really got me thinking is the concurrent sychronized and non-synchronized access.
What happens when Thread A is in doing a "get" while Thread B is entering the sychronized block for the "put"?
I assume that since the map object is not locked it will go straight into the "put" and bang ...right?
Somehow this looks like the optimal usecase for the FastHashMap from collections ...but since this code needs to be very portable this might be a problem because of the double-checked locking idiom.
Another option would be using the StaticBucketMap.
What do you guys think?
If you consider this too OT please reply off list.
cheers -- Torsten
-- Whirlycott Philip Jacob [EMAIL PROTECTED] http://www.whirlycott.com/phil/
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]