I know java Hashmap has a capacity and load factor parameter.So , if the number of items in this hashmap is more than capacity* load factor, a new hashmap will be reconstructed.I have some questions about the re-constructions of it:
- The previous hashmap will be reclaimed or still be in use if the reconstruction happened?
- since we need a larger size hashmap , so , will the hash function be changed ?
- For ConcurrentHashMap , what if one thread is inserting(Of cource, this insert operation has lead to a re-construction) and another thread is reading?For example, it will read from the old hashmap or from the new hashmap?
It's still the same hashmap, just the internal storage is reconstructed. After reconstruction the old bucket array is not needed anymore and could be gc'ed.
Update: Internally
HashMaphasNode<K,V>[] table. During resize a new array will be constructed, the elements are moved and thentableis replaced with the new array. After that operation the map itself would not reference the old array anymore so unless there are no other references (which is unlikely due totablebeing package private) it is elligible for gc.No, the hash function won't change. It generally doesn't depend on the number of buckets but the generated hash will be adjusted to get the correct bucket (e.g. by applying a modulo)
Update:
HashMapcalculates the bucket index like this:(size - 1) & hash,hashis the return value of the key'shashCode()method, which doesn't depend on the map itself.I'd have to guess here (I'll look up the code later) but I assume as long as threads are reading from the old buckets they'll still be in use and will be freed later.
Update: I had a quick look at the
ConcurrentHashMapsources and there are reference to the currenttablewhich is used byget()and a possiblenextTablewhich is the target for resize operations. During resize the elements are transferred tonextTableand at the endtableis set tonextTable, effectively switching tables.This means that during resizing the old table is still read and at some point it gets replaced. During insert operations there might be some blocking, e.g. by using synchronized blocks, especially if a resize is needed or already being performed.
The documentation also hints at this:
This means that
getwon't block butput,removeetc. might block at some point.