Is locking necessary for a single point lookup table?

I have a singleton below. I have multiple threads using a search to check if the values ​​are valid. Some time has passed since I did something with shared memory, so I want to make sure which locks are needed. I'm not sure if I need parallel dialing instead of a HashSet, since I only insert values ​​once.

I have a property [MethodImpl(MethodImplOptions.Synchronized)]in the instance property, because I read that the properties are not synchronized (it makes sense). This should prevent the creation of multiple instances, although I'm not sure I should really worry about this (just the extra cost of reloading the set?).

Should I make a FipsIsValidSyncrhonized function or use some kind of parallel dialing? Or not needed?

public class FipsLookup
{
    private static FipsLookup instance;

    private HashSet<string> fips;

    private FipsLookup()
    {
        using (HarMoneyDB db = new HarMoneyDB())
        {
            instance.fips = new HashSet<string>(db.Counties.Select(c => c.FIPS).ToArray());
        }
    }

    [MethodImpl(MethodImplOptions.Synchronized)]
    public static FipsLookup Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new FipsLookup();
            }
            return instance;
        }
    }

    public static bool FipsIsValid(string fips)
    {
        var instance = FipsLookup.Instance;

        return instance.fips.Contains(fips);
    }
}
+4
source share
3 answers

Should I make the FipsIsValid Syncrhonized function or use some kind of parallel dialing? Or not needed?

I think the key to this is the fact that you only search on HashSet, not mutate it. Since it is initialized once, and only once, there is no need to synchronize the search.

If you decide that as you need to mutate it, you need to use the correct lockor parallel collection.

On the side of the note, you can simplify your singleton by initializing the instance field once inside the static constructor:

private static FipsLookup instance;
static FipsLookup() 
{
    instance = new FipsLookup();
}

Instance , [MethodImpl(MethodImplOptions.Synchronized)]:

public static FipsLookup Instance
{
    get
    {
        return instance;
    }
}
+4

, Instance, . . ( ).

, . . :

( ECMA), HashSet. ( Microsoft CLR, ), , .

MethodImplOptions.Synchronized. , , .

, Lazy<T>, , .

MethodImplOptions.Synchronized , . , () . , , .

+4

The HashSet class is not thread safe, and there is no guarantee that you can access it from multiple threads, and everything will be fine. Instead, I would rather use ConcurrentDictionary.

+1
source

All Articles