Hashtable and synchronization
Hashtable is, of course, the original synchronized Dictionary in Java. It’s now considered deprecated and Collections.synchronizedMap(new HashMap()) would generally be the preferred way to do it. But, code out there certainly still exists that uses Hashtable, especially on some older APIs.
Anyhow, Hashtable was retrofitted to implement Map and in particular the entrySet() method that returns Map.Entry objects. Map.Entry has methods to get the key and value and set the value. Since this is in the unlocked Map world, calling these methods would be a bad idea on an Entry from a Hashtable.
So, something like this would be broken (please excuse any typos, just doing this on the fly):
Hashtable ht = new Hashtable();
ht.put(“k”, “v”);
Set entries = ht.entrySet();
Map.Entry entry = (Map.Entry) entries.iterator().next();
String k = (String)entry.getKey();
String v = (String)entry.getValue();
entry.setValue(“v2″);
For the last 3 lines, all of these are touching state in the Hashtable that is protected there by synchronization on the Hashtable instance. So, the correct way to write this code is:
Hashtable ht = new Hashtable();
ht.put(“k”, “v”);
Set entries = ht.entrySet();
Map.Entry entry = (Map.Entry) entries.iterator().next();
synchronized(ht) {
String k = (String)entry.getKey();
String v = (String)entry.getValue();
entry.setValue(“v2″);
}
Note that even if you are only doing getKey() or getValue(), it’s still broken not to synchronize as the Java Memory Model will make no guarantee that you’ll ever see an update by another thread in this case.
There are some similar but different weird constraints when you use iterators on synchronized wrappers from Collections. The javadoc says:
It is imperative that the user manually synchronize on the returned list when iterating over it:
List list = Collections.synchronizedList(new ArrayList());
…
synchronized(list) {
Iterator i = list.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}
Tricky. Surprising to me when I first saw it…

Hi! My name is Alex Miller and I live in St. Louis. I write code for a living and currently work for
I’d argue that the
Collections.synchronized*methods are only for dealing with legacy code as well…ConcurrentHashMapis a much more scalable solution.Yes, I would in general agree, although there are some rare cases where I’ve used the synch wrappers.
Interestingly, your last example becomes more nefarious when the iterator is implicit, as in:
for (Object o : list) { foo(o); }
Who expected the need for those to be synchronized as well? But I am still unconvinced this is correct. (Not saying you’re wrong, I’m just skeptical, and since the source is close by…)
If you dont synchronize your Hashtable or Collections.synchronizedList when you iterate on it, you risk getting an ConcurrentModificationException if another thread mutate the data structure while you perform the iteration. Which I guess is the best case scenario, the worse case is getting corrupted data, such as the same data twice, or missing data.