静态功能需要锁定机制吗?

时间:2015-08-17 10:29:16

标签: c# multithreading

我创建了一个包含5个静态函数的CommonUtils.cs文件(因此我可以将这个.cs复制到Visual Studio中的其他项目,因为我开发了不同的C#应用​​程序)以及我有很多源文件。

现在,我已将项目编译为DLL。此DLL由IIS服务器作为应用程序托管。许多客户使用此dll执行某些操作,比如他们生成报告。

我被告知在这种情况下不能慷慨地使用“静态函数”并且应该应用它们,因为没有锁定,“锁定”机制,单个程序实例的多个线程或程序的多个实例,两者都可以出乎意料地表现出来这是真的吗?

4 个答案:

答案 0 :(得分:11)

  

我被告知不得使用“静态功能”   慷慨地在这种背景下应该应用它们,“锁定”   机制因为没有锁定,单个实例的多个线程   程序或程序的多个实例都可以表现   不料。这是真的吗?

让我们一块一块地打破它。什么是静态类?

  

静态类与非静态类基本相同,但是   有一个区别:静态类无法实例化。   换句话说,您不能使用new关键字来创建变量   类类型。因为没有实例变量,所以您可以访问   使用类名本身的静态类的成员。

CLR如何处理静态类?

  

与所有类类型的情况一样,静态的类型信息   .NET由.NET Framework公共语言运行库(CLR)加载   当加载引用该类的程序时。该程序   无法准确指定何时加载类。 然而,   保证加载并初始化其字段   在第一个引用类之前调用​​的静态构造函数   您计划中的时间。静态构造函数只调用一次,   并且静态类在的生命周期内保留在内存中   程序所在的应用程序域

为什么 可能 需要锁定?

基本上,当我们有比赛条件时需要锁定。当有人可能读取其他人可能在同一时间改变他们的数据。两个独立的线程可以访问共享资源,并且没有任何机制可以阻止这种情况。为了回答你的问题,你首先要回答另一个问题。

您的静态方法是否访问共享资源并且可能存在任何竞争条件?如果这是真的,那么你需要使用锁定。否则,不需要它。

有关静态类的更多信息,请查看here。 如果您需要有关线程同步技术的更多信息,请查看here

答案 1 :(得分:9)

函数是不可变的,因此在调用函数时不需要同步。函数参数是可变的,但每次调用都有自己的本地副本。无需同步。

当多个线程处理相同的数据并且至少有一个编写器时,需要进行同步。这是关于线程之间共享的任何变量。需要注意静态变量和静态变量可以访问的任何实例变量。

答案 2 :(得分:0)

听起来你有一个类库。以下是Microsoft针对需要支持多线程的类库的指南:

  • 如果可能,请避免同步。对于使用频繁的代码尤其如此。例如,可以调整算法以容忍竞争条件而不是消除竞争条件。不必要的同步会降低性能并导致死锁和竞争条件的可能性。

  • 默认情况下,使静态数据(在Visual Basic中为Shared)线程安全。

  • 默认情况下,不要使实例数据线程安全。添加锁以创建线程安全代码会降低性能,增加锁争用,并可能导致死锁发生。在常见的应用程序模型中,一次只有一个线程执行用户代码,这最大限度地减少了对线程安全的需求。因此,默认情况下,.NET Framework类库不是线程安全的。

  • 避免提供改变静态的静态方法。在常见的服务器方案中,静态状态在请求之间共享,这意味着多个线程可以同时执行该代码。这开启了线程错误的可能性。考虑使用将数据封装到不在请求之间共享的实例的设计模式。此外,如果静态数据被同步,则改变状态的静态方法之间的调用可能导致死锁或冗余同步,从而对性能产生负面影响。

https://msdn.microsoft.com/en-us/library/1c9txz50(v=vs.110).aspx

复制

答案 3 :(得分:-1)

解释“LOCK”来自MSDN说:
lock关键字通过获取给定对象的互斥锁,执行语句,然后释放锁来将语句块标记为关键部分。

lock关键字确保一个线程不进入代码的关键部分,而另一个线程处于临界区。如果另一个线程试图输入一个锁定的代码,它将等待,阻止,直到该对象被释放

参考文献:
https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx

最好在多线程中使用LOCK而不是每次都创建静态函数。