That is not quite
correct,
since the FastHashMap class delegates all calls to the
underlying Hashmap,
there are two
levels of synchronization, or more accurately, two different
object locks that
are being manipulated in order to optimize the instance for
fast read lookups
which won't affect the underlying hash structure. In "fast mode",
the get()
operation simply calls the get() method on the underlying HashMap instance.
Also in
fast
mode, the put() operation obtains the lock on the FastHashmap
instance,
not the
underlying Hashmap that is being used. Just a guess, but this is
to
prevent
concurrent threads from accessing this particular operation in
fast
mode, which does
simply this: 1) obtain the lock for the FastHashMap
instance,
2)clone the
underlying java.util.HashMap--this is a shallow clone only,
an
important point
since the put() operation will most likely alter the underlying
structure
of the hashmap
itself including its internal bucket structure, then
3)reassign
the internal
Hashmap instance to the clone. To answer the original
question,
2 and 3 above are
done so that threads other than the one executing the put()
operation can
continue to call the get() method without blocking, which is
in
essence, a
"snapshot" of the hashmap. Since reference assignments are atomic
within
the jvm, you will
not get into a situation where a call to get() in one thread
is being garbled
by the put() in another. The key point is that in fast mode,
the get() does
not block at all, while the put() locks only the FastHashMap
wrapper
instance. As soon
as the temporary clone assignment back to this.map is
executed,
all future get()
calls will operate on the updated Hashmap. Of course, lots
of
put() calls will
block in fast mode, thus the need to call setFast(true)
after
you have finished
initialization :).
Jin
-Original Message-From: Calvin Yu
[mailto:[EMAIL PROTECTED]]Sent: Monday, July 02, 2001 8:15
AMTo: [EMAIL PROTECTED]; suhasSubject: Re:
Fast Hashmap doubt .
If you look at FashHashMap.get(Object key),
you'll notice that the call to map.get() is not synchronized. If
FashHashMap.put() isn't implemented like this, you'll run into a race
condition when one thread calls map.put() and another calls
map.get().
Calvin
- Original Message -
From:
suhas
To: [EMAIL PROTECTED]
Sent: Saturday, July 01, 2000 5:47
AM
Subject: Fast Hashmap doubt .
I was going through put ( ) and putAll ( )
methods in Fast HashMap code in the struts . But did not get why we need to
clone the HashMap and add a entry to that cloned map then move that cloned
map to original HashMap . In multi- threaded enviornment anyway we
synchronized the code that accesses the HashMap in the put method ..
?
public Object put(Object
key, Object value) {
if
(fast)
{
synchronized (this) {
// IF U synchronize the code like this
then easily only one thread can manipulate the HashMap
HashMap temp = (HashMap) map.clone();
// What this do then
?
Object result = temp.put(key, value);
//
map =
temp; //
return
(result);
} } else
{
synchronized (map)
{
return (map.put(key,
value));
} }
}