You certainly can lock on the Hashtable
object, just as you can use any reference type instance in .NET in a lock
statement. However, it's generally considered an inferior approach, mainly because it's harder to keep track of how the code is using locking when one or more of the lock objects is available to other parts of the code, where they might use it for locking as well (again, inadvisably, but you'd be surprised at what code people write sometimes).
For locking in general, a separate locking object is preferable. I'll note that in your code example, the _ht
should be readonly
, and if you add a separate locking object (e.g. lockObj
), that should be readonly as well.
That said, the singleton scenario shouldn't be implemented this way at all. Instead, you should either use the CLR's own static initialization, or the Lazy<T>
class:
private static readonly Hashtable _ht = InitializeTable();
internal static Hashtable GetHT() { return _ht; }
private static Hashtable InitializeTable()
{
Hashtable table = new Hashtable();
LoadHt(table);
return table;
}
Or:
private static readonly Lazy<Hashtable> _ht = new Lazy<Hashtable>(() => InitializeTable());
internal static Hashtable GetHT() { return _ht.Value; }
private static Hashtable InitializeTable()
{
Hashtable table = new Hashtable();
LoadHt(table);
return table;
}
The latter is useful when you have other members of the type that might be accessed, but you want to make sure initialization of the hash table is delay as long as possible (e.g. if it's possible no code would ever actually access it, so you can avoid initializing it altogether).
(I changed everything to static
because you described your scenario as a singleton, and in that case only static
members make sense for the code example).
Finally I'll note that the Hashtable
class is extremely dated. As a non-generic class, you really should seriously consider upgrading the code to use the now-decade-old generic type. The Dictionary<TKey, TValue>
class is the most direct replacement, but people sometimes use Hashtable
as a simple set, for which the HashSet<T>
data structure would be more appropriate.