简体   繁体   中英

Thread safety consideration for static property as an Instance of that class

Please consider this code:

public class BusinessClass
{
    static BusinessClass myClass { get; set; }
    Repository repo;

    public BusinessClass()
    {
        if (repo == null)
            repo = new RepositoryClass();
    }

    public static BusinessClass Instance
    {
        get
        {
            if (myClass == null)
                myClass = new BusinessClass();
            return myClass ;
        }
    }

    public void Update(Entity Item)
    {
        repo.Update(Item);
    }
}

and I want to use this BL in my web page like this:

BusinessClass.Instance.Update(Item);

My question is: is this code problematic for thread safety? Can two people come together at the same time in Update method?

Thanks

First case - asp.net session lock

If you use asp.net forms and the session of asp.net, then the session is lock the entire call for all users, so you don't need to extra take care to synchronize that.

Relative questions :

Does ASP.NET Web Forms prevent a double click submission?
Trying to make Web Method Asynchronous
Web app blocked while processing another web app on sharing same session
What perfmon counters are useful for identifying ASP.NET bottlenecks?
Replacing ASP.Net's session entirely

Second case - the local thread.

If you not use the asp.net session, or if you open extra threads on the same call , then you need to lock the manipulation of static data.

public class BusinessClass
{
    private static readonly object oLock = new object();

    static BusinessClass myClass { get; set; } = null;
    Repository repo;

    public BusinessClass()
    {
        if (repo == null)
            repo = new RepositoryClass();
    }

    public static BusinessClass Instance
    {
        get
        {
            if myClass == null)
            {
                lock (oLock)
                {
                    if myClass == null)
                        myClass = new BusinessClass();
                }
            }
            return myClass  
        }
    }

    public void Update(Entity Item)
    {
        repo.Update(Item);
    }
}

Final case - the global change

If you wish to double check a global change on the database or on the files, or on anything that can change from simulate edit of the system - on a web platform that runs on web garden (multi pools for the same site)... and ignore the session...

Then you need mutex to synchronize all calls.

By using mutex , you also need to check just before the update, that the record is still the same and if not you signaling that some one else change it and the current user will overwrite it.

More to consider - multi-user environment.

Think this scenario.
User A and B, load the same page, the same data, and each of one change them.

the users are going to save each data - not the same moment - but with a lot of time different. The data that you write down is the last one saved. One of the user will lost their changes.

So you need some more to consider and made a lot more synchronization signaling in a multi user environment if your users update the same data - beyond the locking system.

It's not thread-safe. Here is just one example of what could happen:

Thread1: if (myClass == null) <- receives true because it's null

Thread1: [temp1] = new BusinessClass(); <-- [temp1] exists implicitly in Thread 1

Thread2: if (myClass == null) <- receives true because it's still null

Thread2: [temp2] = new BusinessClass(); <-- [temp2] exists implicitly in Thread 2

Thread2: myClass = [temp2];

Thread2: return myClass; <-- returns second instance created

Thread1: myClass = [temp1];

Thread1: return myClass; <-- returns first instance created

Now each thread holds a different instance of the "singleton" Instance .


An easy-to-use thread-safe direct alternative would be to use a Lazy<BusinessClass> to hold your singleton instance instead of myClass .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM