Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make static method thread safe?

I have written a static class which is a repository of some functions which I am calling from different class.

public static class CommonStructures
{
    public struct SendMailParameters
    {
        public string To { get; set; }
        public string From { get; set; }
        public string Subject { get; set; }
        public string Body { get; set; }
        public string Attachment { get; set; }
    }
}

public static class CommonFunctions
{
    private static readonly object LockObj = new object();
    public static bool SendMail(SendMailParameters sendMailParam)
    {
        lock (LockObj)
        {
            try
            {
                //send mail
                return true;
            }
            catch (Exception ex)
            {
                //some exception handling
                return false;
            }
        }
    }

    private static readonly object LockObjCommonFunction2 = new object();
    public static int CommonFunction2(int i)
    {
        lock (LockObjCommonFunction2)
        {
            int returnValue = 0;
            try
            {
                //send operation
                return returnValue;
            }
            catch (Exception ex)
            {
                //some exception handling
                return returnValue;
            }
        }
    }
}

Question 1: For my second method CommonFunction2, do I use a new static lock i.e. LockObjCommonFunction2 in this example or can I reuse the same lock object LockObj defined at the begining of the function.

Question 2: Is there anything which might lead to threading related issues or can I improve the code to be safe thread.

Quesiton 3: Can there be any issues in passing common class instead of struct.. in this example SendMailParameters( which i make use of wrapping up all parameters, instead of having multiple parameters to the SendMail function)?

Regards, MH

like image 731
user1961100 Avatar asked Jun 07 '13 05:06

user1961100


People also ask

Can static method be thread safe?

A data type or static method is threadsafe if it behaves correctly when used from multiple threads, regardless of how those threads are executed, and without demanding additional coordination from the calling code.

How do I make a static variable thread safe?

As for the original question - Hashtable by itself is synchronized. So, if you are declaring a static final Hashtable and also intializing it at the time of declaration itself, all operations will be thread-safe on this Hashtable instance without you having to write any code for synchronization.

Can static methods be protected?

Usually there isn't much reason to declare a private or protected method as static. Static methods are usually public. But when the behavior of a method does not affect or is affected by the state of the current instance, declaring it static can be a way to document this fact.


1 Answers

Question 1: For my second method CommonFunction2, do I use a new static lock i.e. LockObjCommonFunction2 in this example or can I reuse the same lock object LockObj defined at the begining of the function.

If you want to synchronize these two methods, then you need to use the same lock for them. Example, if thread1 is accessing your Method1, and thread2 is accessing your Method2 and you want them to not concurrently access both insides, use the same lock. But, if you just want to restrict concurrent access to just either Method1 or 2, use different locks.

Question 2: Is there anything which might lead to threading related issues or can I improve the code to be safe thread.

Always remember that shared resources (eg. static variables, files) are not thread-safe since they are easily accessed by all threads, thus you need to apply any kind of synchronization (via locks, signals, mutex, etc).

Quesiton 3: Can there be any issues in passing common class instead of struct.. in this example SendMailParameters( which i make use of wrapping up all parameters, instead of having multiple parameters to the SendMail function)?

As long as you apply proper synchronizations, it would be thread-safe. For structs, look at this as a reference.

Bottomline is that you need to apply correct synchronizations for anything that in a shared memory. Also you should always take note of the scope the thread you are spawning and the state of the variables each method is using. Do they change the state or just depend on the internal state of the variable? Does the thread always create an object, although it's static/shared? If yes, then it should be thread-safe. Otherwise, if it just reuses that certain shared resource, then you should apply proper synchronization. And most of all, even without a shared resource, deadlocks could still happen, so remember the basic rules in C# to avoid deadlocks. P.S. thanks to Euphoric for sharing Eric Lippert's article.

But be careful with your synchronizations. As much as possible, limit their scopes to only where the shared resource is being modified. Because it could result to inconvenient bottlenecks to your application where performance will be greatly affected.

    static readonly object _lock = new object();
    static SomeClass sc = new SomeClass();
    static void workerMethod()
    {
        //assuming this method is called by multiple threads

        longProcessingMethod();

        modifySharedResource(sc);
    }

    static void modifySharedResource(SomeClass sc)
    {
        //do something
        lock (_lock)
        {
            //where sc is modified
        }
    }

    static void longProcessingMethod()
    {
        //a long process
    }
like image 150
aiapatag Avatar answered Oct 13 '22 06:10

aiapatag