I wonder why java.util.Hashtable
methods perform operations on elements array through locally assigned variable, instead of accessing class member directly. Does it has something to do with synchronization (keeping elements array in consistent state between method calls?)
For example : Entry<?,?> tab[] = table;
in
private void addEntry(int hash, K key, V value, int index) {
420 modCount++;
421
422 Entry<?,?> tab[] = table;
423 if (count >= threshold) {
424 // Rehash the table if the threshold is exceeded
425 rehash();
426
427 tab = table;
428 hash = key.hashCode();
429 index = (hash & 0x7FFFFFFF) % tab.length;
430 }
or in
456 public synchronized V put(K key, V value) {
457 // Make sure the value is not null
458 if (value == null) {
459 throw new NullPointerException();
460 }
461
462 // Makes sure the key is not already in the hashtable.
463 Entry<?,?> tab[] = table;
464 int hash = key.hashCode();
465 int index = (hash & 0x7FFFFFFF) % tab.length;
466 @SuppressWarnings("unchecked")
467 Entry<K,V> entry = (Entry<K,V>)tab[index];
468 for(; entry != null ; entry = entry.next) {
469 if ((entry.hash == hash) && entry.key.equals(key)) {
470 V old = entry.value;
471 entry.value = value;
472 return old;
473 }
474 }
475
476 addEntry(hash, key, value, index);
477 return null;
478 }
I feel bad leaving only comments, this question deserves a proper answer, so here's a quick attempt to rehash (ha) those comments.
Hashtable
is synchronized (all public methods are synchronized
, or return a synchronized collection ( keySet()
, entrySet()
, values()
)), which makes it thread safe (Some rules & restrictions may apply) rehash()
method is protected
: it can be invoked from a subclass. synchronized
, so an instance of a subclass could invoke rehash()
concurrently to another of those methods that need to access table
. table
, those methods save a local copy of the reference to the array, and then can safely work with that local array: if rehash()
is called, it will build a new array without interfering with other threads working on the old one. Version from JDK 1.0.2 was already like that (found it here , the Windows .exe
is self-extractible zip file, so unzip
deals with that, and in there you'll find src.zip
-- interesting to see Hashtable.java
with 3 classes inside, no inner classes as those were introduced in 1.1).
This design encourages inheriting Hashtable
to benefit from its functionality, but composition should be favored instead. I found a bug entry that is specific to subclasses of Hashtable
(although not about thread safety), in which Josh Bloch says:
This sort of problem can be avoided by using delegation rather than subclassing.
Quoting @pvg in comments, for a nice summary:
A somewhat broader answer is that this is basically an early 90s design that has just had a long life and it shows. It's a class that tries to be both threadsafe and extensible through subclassing at the same time, something the class library avoids in later design iterations.
这很简单 - rehash()
将重写table
字段,因此将它们保存到临时变量以便以后访问。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.