Re: Cannot seem to lock HashMap
This is a good point, but I am not sure if you are correct (this is
getting a bit out of my league). It appears that the HashMap.Entry
DOES depends on the table.length - so it is sensitive to changes in
size.
But I cannot say for sure if this will cause the behavior or problems
you mention above (return NULL becuase of unsynchronized get()
method). One thing that leads me to think you ARE correct is the
implementation of Hashtable HAS a synchronized get() method. But it
seems strange to me that HashMap would have such a BIG vunerability in
it - but perhaps that is what you get when using unsynchronized
HashMap vs. Hashtable.
Any Java experts care to expand on this?
I think that tomorrow I will take the HashMap source code and run some
tests to prove or disprove this theory, since I cannot tell by looking
at it. But if true, then I will need to also synchronize the get()
method in my wrapper class.
Below methods are from HashMap.java (1.5.0_12):
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key ||
key.equals(k)))
return e.value;
}
return null;
}
static int indexFor(int h, int length) {
return h & (length-1);
}
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key ||
key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
void addEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];
table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}