Is it possible to use a Hashtable as a lock object?

I have the following code which "_ht" represents the Hashtable representing the cache and "_isLoaded" represents if it is loaded.

There are many processes on our system accessing the "_ht" object, and I need them to wait to see if they are loaded.

Is "_ht" being used as the lock object? Should I be using a dedicated class for this scenario?

It is important to note that this class is SINGLETON.

private Hashtable _ht = new Hashtable();
private bool _isLoaded = false;

internal Hashtable GetHT()
        {
            if (_isLoaded == false)
            {
                lock (_ht)
                {
                    if (_isLoaded == false)
                    {
                        LoadHt(_ht);
                    }
                }
            }

            return _ht;
        }

      

+3


source to share


3 answers


Of course, you can lock an object Hashtable

, just like you can use any .NET reference type instance in a statement lock

. However, it is generally considered a lower approach, mainly because it is harder to track how the code is using locking when one or more lock objects are available to other parts of the code where they can also use it to lock (again, impractical, but you'd be surprised at the kind of code people write sometimes).

For locking, a separate lock object is generally preferred. I noticed that in your example code there _ht

should be readonly

, and if you add a separate lock object (for example lockObj

) it should be readonly as well.

However, the singleton script shouldn't be implemented at all. You should instead use your own CLR static initialization or class Lazy<T>

:

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 can be accessed, but you want to initialize the hash table as long as possible (for example, if possible, any code would never access it, so you you may not initialize it at all).

(I changed everything to static

because you described your scenario as singleton, in which case only members static

make sense for the code example).

Finally, note that the class is Hashtable

extremely deprecated. As a non-generic class, you really should seriously consider updating your code to use a ten-year generic type. The class Dictionary<TKey, TValue>

is the most direct replacement, but people sometimes use it Hashtable

as a simple set, for which a data structure would be more appropriate HashSet<T>

.

+10


source


if you want the first thread to come here to initiate it. but usually a lock object is used for this.



private Hashtable _ht = new Hashtable();
private bool _isLoaded = false;
private object lockObj = new object();

internal Hashtable GetHT()
{
    if (_isLoaded == false)
    {
         lock (lockObj)
         {
             if (_isLoaded == false)
             {
                 LoadHt(_ht);
             }
         }
     }

     return _ht;
}

      

+2


source


The object itself is not locked (protected). The reference used in the blocking keyword is used to mark or mark a section of code that should not run concurrently with any other (or the same) piece of code that used the same object reference. It doesn't actually affect the object itself. So the answer is yes , you can use an existing HashTable instance in the lock statement.

"Best practice" , but it is to define a private object to lock, or a private variable of a static object to protect data common to all instances.

private Object thisLock = new Object();

      

Edited Thanks @PeterDuniho for pointing

+1


source







All Articles