While Hashtable is not generic, is is thread-safe so long as you use it right (one writer, multiple readers, no enumeration).
Thread Safety
To support one or more writers, all
operations on the Hashtable must be
done through the wrapper returned by
the Synchronized method.
Enumerating through a collection is
intrinsically not a thread-safe
procedure. Even when a collection is
synchronized, other threads could
still modify the collection, which
causes the enumerator to throw an
exception. To guarantee thread safety
during enumeration, you can either
lock the collection during the entire
enumeration or catch the exceptions
resulting from changes made by other
threads.
It is different than a dictionary though -- it will return null, not throw a KeyNotFoundException if you try to get a value that doesn't exist (so storing null values can be problematic). It's a very useful collection if you know you'll never have more than one thread trying to add a new key, and can deal with the null issue.