Below is a class of fasthashmap I was reading commons-beanutils.jar,
Read from aboveCodeFinally, there is a red code block. Can someone tell me why the Blue Code cannot be changed to "Return (Map. Put (Key, value ));"?
What is the role of map. Clone?
/*
* copyright 2001-2004 the Apache Software Foundation
*
licensed under the Apache license, version 2.0 (the "License");
* You may
not use this file except T in compliance with the license.
* You may obtain a
copy of the license at
* http://www.apache.org/licenses/LICENSE-2.0
*
unless required by applicable law or agreed to in writing, software
*
distributed under the license is distributed on an "as is" basis,
* Without
warranties or conditions of any kind, either express or implied.
* See the
license for the specific language governing permissions and
* limitations
under the license.
*/
package Org. apache. commons. collections;
Import java. util. collection;
Import
Java. util. concurrentmodificationexception;
Import
Java. util. hashmap;
Import java. util. iterator;
Import
Java. util. Map;
Import java. util. Set;
/**
* <P> a customized Implementation
<Code> JAVA. util. hashmap </code> designed
* To operate in
Multithreaded environment where the large majority
* Method callare
Read-Only, instead of structural changes. When operating
* In "fast" mode,
Read callare non-synchronized and write callperform
* Following
Steps: </P>
* <Ul>
* <Li> clone the existing
Collection
* <Li> perform the modification on the clone
*
<Li> Replace the existing collection with the (modified) Clone
*
</Ul>
* <P> when first created, objects of this class default
"Slow" mode, where
* All accesses of any type are synchronized but no
Cloning takes place. This
* Is appropriate for initially populating
Collection, followed by a switch
* To "fast" mode (by calling
<Code> setfast (true) </code>) after Initialization
* Is
Complete. </P>
*
* <P> <strong> note </strong>: If
You are creating and accessing
* <Code> hashmap </code> only
Within a single thread, you should use
*
<Code> JAVA. util. hashmap </code> directly (with no synchronization ),
For
* Maximum performance. </P>
*
*
<P> <strong> note </strong>: <I> this class is not
Cross-platform.
* Using it may cause unexpected failures on some
Ubuntures. </I>
* It suffers from the same problems as
Double-checked locking idiom.
* In particle, the instruction that clones
The internal collection and
* Instruction that sets the internal
Reference to the clone can be executed
* Or perceived out-of-order. This
Means that any read operation might fail
* Unexpectedly, as it may be
Reading the state of the internal collection
* Before the internal
Collection is fully formed.
* For more information on the double-checked
Locking idiom, see
* <A href =" Http://www.cs.umd.edu /~ API/Java/MemoryModel/doublecheckedlocking.html ">
*
Double-checked locking idiom is broken
Declaration </a>. </P>
*
* @ Since commons collections
1.0
* @ Version $ revision: 1.1 $ Date: 2004/05/10 19:51:13 $
*
*
@ Author Craig R. Mcclanahan
* @ Author stephen colebourne
*/
Public
Class fasthashmap extends hashmap {
/**
* The underlying map we are managing.
*/
Protected hashmap map = NULL;
/**
* Are we currently operating in "fast" mode?
*/
Protected Boolean fast = false;
// Constructors
//
----------------------------------------------------------------------
/**
* Construct an empty map.
*/
Public
Fasthashmap ()
Unknown macro: {super ();
This. Map = new hashmap ();}
/**
* Construct an empty map with the specified capacity.
*
* @ Param capacity the initial capacity of the empty Map
*/
Public fasthashmap (INT capacity)
Unknown macro: {super ();
This. Map = new hashmap (capacity );}
/**
* Construct an empty map with the specified capacity and Load
Factor.
*
* @ Param capacity the initial capacity of the empty
Map
* @ Param factor the load factor of the new map
*/
Public fasthashmap (INT capacity, float factor)
Unknown macro: {super ();
This. Map = new hashmap (capacity, factor );}
/**
* Construct a new map with the same mappings as the specified
Map.
*
* @ Param map the map whose mappings are to be
Copied
*/
Public fasthashmap (MAP map)
Unknown macro: {super ();
This. Map = new hashmap (MAP );}
// Property access
//
----------------------------------------------------------------------
/**
* Returns true If this map is operating in fast
Mode.
*
* @ Return true If this map is operating in fast
Mode
*/
Public Boolean getfast ()
Unknown macro: {return
(This. Fast );}
/**
* Sets whether this map is operating in fast mode.
*
* @ Param fast true if this map shoshould operate in fast mode
*/
Public void setfast (Boolean fast)
Unknown macro: {This. Fast = fast;
}
// MAP access
//
----------------------------------------------------------------------
//
These methods can forward straight to the wrapped map in 'fast 'mode.
//
(Because they are query methods)
/**
* return the value to which this map maps the specified key.
Returns
* null
If the map contains no mapping
for this key, or if
* There is a mapping with a value of
null
. use the
*
containskey ()
method to disambiguate these
cases.
* @ Param key the key whose value is to be
returned
* @ return the value mapped to that key, or null
*/
Public object get (Object key) {
If (FAST)
Unknown macro: {return
(Map. Get (key ));}
Else {
Synchronized (MAP)
Unknown macro: {return
(Map. Get (key ));}
}
}
/**
* Return the number of key-value mappings in this
Map.
*
* @ Return the current size of the map
*/
Public int size (){
If (FAST)
Unknown macro: {return
(Map. Size ());}
Else {
Synchronized (MAP)
Unknown macro: {return
(Map. Size ());}
}
}
/**
* Return <code> true </code> If this map contains
No mappings.
*
* @ Return is the map currently empty
*/
Public Boolean isempty (){
If (FAST)
Unknown macro: {return
(Map. isempty ());}
Else {
Synchronized (MAP)
Unknown macro: {return
(Map. isempty ());}
}
}
/**
* Return <code> true </code> If this map contains
Mapping for
* Specified key.
*
* @ Param key the key
To be searched
* @ Return true if the map contains the key
*/
Public Boolean containskey (Object key ){
If (FAST)
Unknown macro: {return
(Map. containskey (key ));}
Else {
Synchronized (MAP)
Unknown macro: {return
(Map. containskey (key ));}
}
}
/**
* Return <code> true </code> If this map contains
One or more keys Mapping
* To the specified value.
*
*
@ Param value the value to be searched
* @ Return true if the map
Contains the value
*/
Public Boolean containsvalue (object value)
{
If (FAST)
Unknown macro: {return
(Map. containsvalue (value ));}
Else {
Synchronized (MAP)
Unknown macro: {return
(Map. containsvalue (value ));}
}
}
// Map Modification
//
----------------------------------------------------------------------
//
These methods perform special behaviour in 'fast 'mode.
// The map is
Cloned, updated and then assigned back.
// See the comments at the top
To why this won't always work.
/**
* Associate the specified value with the specified key in
This map.
* If the map previusly contained a mapping for this key,
Old
* Value is replaced and returned.
*
* @ Param key
The key with which the value is to be associated
* @ Param value
Value to be associated with this key
* @ Return the value previusly
Mapped to the key, or null
*/
Public object
Put (Object key, object Value ){
If (FAST)
{
Synchronized (this)
{
Hashmap temp = (hashmap)
Map. Clone ();
Object result =
Temp. Put (Key, value );
Map =
Temp;
Return
(Result );
}
} Else {
Synchronized (MAP ){
Return
(Map. Put (Key, value ));
}
}
}
...... The subsequent Code does not need to be pasted.
Today, I thought about it as follows:
The so-called fasthashmap is mainly to transform the original thread-insecure hashmap into a thread-safe hashmap. There are also two modes:
In fast mode, all read operations are mutually exclusive, and all read and write operations are mutually exclusive. To ensure that the map is not modified after reading, the clone policy is used, that is, memory copy. What is memory copy? If one thread a is reading and one thread B is writing, then the map of the B operation is a copy of the map of the operation, so that no matter what B does, it will not affect the operation, this ensures that no concurrent repair exists.
When the fast mode is no longer used, the whole map can only be locked for thread synchronization, which ensures the thread security of the map. However, all the operations of the whole map are only single-threaded, so it's slow.