如何使静态方法的线程安全吗? [英] How to make static method thread safe?

查看:117
本文介绍了如何使静态方法的线程安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个静态类,这是的,我是从不同的类调用一些函数库。

 公共静态类CommonStructures 
{
公共结构SendMailParameters
{
公共字符串为{搞定;组; }
公共字符串从{搞定;组; }
公共字符串主题{搞定;组; }
公共字符串车身{搞定;组; }
公共字符串附件{搞定;组; }
}
}

公共静态类CommonFunctions
{
私人静态只读对象LockObj =新的对象();
公共静态布尔的SendMail(SendMailParameters sendMailParam)
{
锁(LockObj)
{

{
//发送邮件
返回真;
}
赶上(异常前)
{
//一些异常处理
返回FALSE;
}
}
}

私人静态只读对象LockObjCommonFunction2 =新的对象();
公共静态INT CommonFunction2(int i)以
{
锁(LockObjCommonFunction2)
{
INT的returnValue = 0;

{
//发送操作
返回的returnValue;
}
赶上(异常前)
{
//一些异常处理
返回的returnValue;
}
}
}
}



问题1:对于我的第二个方法CommonFunction2,我用一个新的静态锁即LockObjCommonFunction2在这个例子中我也可以重新使用在函数的开头定义相同的锁对象LockObj



问题2:是否有任何可能导致线程相关的问题,我也可以提高代码是安全线



Quesiton 3:难道还有任何问题通过普通类,而不是结构。在这个例子中SendMailParameters(我使用结束了所有的参数,而不是有多个参数sendmail的功能)?



问候,
MH


解决方案

问题1:我的第二个方法CommonFunction2,我用一个新的
静态锁即LockObjCommonFunction2在本实施例还是可以我重用
。在功能的开始时所定义的相同的锁定对象LockObj




如果你想这两种方法进行同步,那么你需要使用相同的锁定他们。例如,如果线程1正在访问你的方法1,1和线程正在访问您的方法2,并且希望他们不要并发访问的两个的内心,使用同一个锁。但是,如果你只是想限制只是或者方法1或2个并发访问,使用不同的锁




问题2:是否有任何可能导致线程相关的
的问题,我也可以提高代码是安全线


$ b $。 b

永远记住,共享资源(如静态变量,文件)不是线程安全的,因为它们很容易被所有线程访问,因此需要申请任何种类的同步(通过锁,信号, 。互斥等)




Quesiton 3:可有任何问题传递,而不是
结构通用类..在这例如SendMailParameters(我使用
包裹了所有的参数,而不是有多个参数
sendmail的功能)?




只要你申请适当同步,这将是线程安全的。对于结构,看作为参考。



底线是,你需要以应用正确同步的任何东西,在一个共享内存。另外,应始终注意的范围你是产卵线程,每个方法是使用变量的状态。难道他们改变了状态或者仅仅依靠变量的内部状态?请问线程总是创建一个对象,尽管它的静态/共享?如果是的话,那么它应该是线程安全的。否则,如果它只是重​​用,某些共享资源,那么你应该申请适当的同步。而且最重要的,甚至无共享资源后,僵局仍然可能发生,所以的记得在C#中的基本规则,以避免死锁的。 P.S。感谢欣快分享埃里克利珀的文章。



不过要小心你同步。尽可能,限制了其范围,以共享资源被修改仅在哪里。因为这可能会导致以不方便瓶颈您的应用中的性能将受到很大的影响。

 静态只读对象_lock =新的对象() ; 
静态SomeClass的SC =新SomeClass的();
静态无效workerMethod()
{
//假设该方法是由多个线程叫做

longProcessingMethod();

modifySharedResource(SC);
}

静态无效modifySharedResource(SomeClass的SC)
{
//做些什么
锁(_lock)
{
//其中SC被修改
}
}

静态无效longProcessingMethod()
{
//一个漫长的过程
}


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

解决方案

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
    }

这篇关于如何使静态方法的线程安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆