静态函数需要锁定机制

本文关键字:机制 锁定 静态函数 | 更新日期: 2023-09-27 18:08:21

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

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

我已经被告知,"静态函数"不能在这种上下文中大量使用,它们应该被应用,一种"锁定"机制,因为没有锁定,单个程序实例的多个线程或程序的多个实例,两者都可能出现意外行为。这是真的吗?

静态函数需要锁定机制

我被告知不能使用"静态函数"慷慨地在这种情况下,他们应该应用,一个"锁定"由于没有锁机制,多个线程的一个实例程序或程序的多个实例,两者都可以表现出乎意料。这是真的吗?

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

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

CLR如何处理静态类?

与所有类类型一样,静态类型的类型信息类是由。net框架公共语言运行库(CLR)加载的。当引用类的程序被加载时。这个项目无法准确指定加载类的时间。但是它是保证被加载并初始化它的字段和静态构造函数在第一个类被引用之前被调用在程序中的时间。静态构造函数只被调用一次,和,静态类在的生命周期内保持在内存中。程序所在的应用程序域

为什么需要锁呢?

基本上,当我们有竞争条件时需要锁。当某人读取数据时,另一个人可能会同时修改数据。两个独立的线程可以访问共享资源,并且没有任何机制可以阻止这种情况。为了得到问题的答案,你必须先回答另一个问题。

你的静态方法是否访问共享资源,是否存在竞争条件?如果是这样,那么就需要使用锁。否则,则不需要。

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

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

当多个线程在相同的数据上工作并且至少有一个写入器时,需要同步。这是关于线程之间共享的任何变量。对于静态变量和任何可被静态变量访问的实例变量,都需要小心。

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

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

  • 使静态数据(在Visual Basic中共享)默认为线程安全

  • 默认情况下不要使实例数据线程安全。添加锁来创建线程安全的代码会降低性能,增加锁争用,并产生死锁发生的可能性。在常见的应用程序模型中,一次只有一个线程执行用户代码,这样就最小化了对线程安全的需求。因此,. net框架类库在默认情况下不是线程安全的。

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

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

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

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

引用:
https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx

在多线程中使用LOCK比每次都创建静态函数要好。