现在,我已经将我的项目编译为 DLL。这个 dll 作为应用程序通过 IIS 服务器进行托管。许多客户使用这个 dll 来执行某些操作,比如生成报告。
我被告知,在这种情况下,“静态函数”不应该被大量使用,并且应该应用“锁定”机制,因为如果没有锁定,单个程序实例的多个线程或多个程序实例都可能表现出意外行为。这是真的吗?
函数是不可变的,因此在调用函数时无需进行同步。函数参数是可变的,但每次调用都有自己的本地副本,因此也无需同步。
当多个线程在处理相同数据并且至少有一个写入器时,需要进行同步。这涉及到任何在线程之间共享的变量。对于静态变量和由静态变量可达的任何实例变量,需要特别注意。
看起来你有一个类库。以下是微软支持多线程的类库的指南:
尽可能避免需要同步。这对于经常使用的代码尤其如此。例如,可以调整算法以容忍竞争条件而不是消除它。不必要的同步会降低性能并创建死锁和竞争条件的可能性。
默认情况下使静态数据(Visual Basic中的Shared)线程安全。
不要默认情况下使实例数据线程安全。添加锁以创建线程安全代码会降低性能,增加锁争用,并创建死锁的可能性。在常见的应用程序模型中,只有一个线程同时执行用户代码,这最小化了对线程安全的需求。因此,.NET Framework类库默认情况下不是线程安全的。
避免提供更改静态状态的静态方法。在常见的服务器场景中,静态状态在请求之间共享,这意味着多个线程可以同时执行该代码。这打开了线程错误的可能性。考虑使用一种将数据封装到不跨请求共享的实例中的设计模式。此外,如果同步了静态数据,则在更改状态的静态方法之间的调用可能会导致死锁或冗余同步,从而对性能产生不利影响。
从https://msdn.microsoft.com/zh-cn/library/1c9txz50(v=vs.110).aspx复制
关于 "LOCK" 的解释,MSDN 上说:
lock 关键词通过获取给定对象的互斥锁、执行语句,然后释放锁,将语句块标记为临界区。
lock 关键字确保一个线程不会在另一个线程进入临界区的同时进入代码的临界区。如果另一个线程尝试进入锁定的代码,则会等待,阻塞,直到该对象被释放。
参考资料:
https://msdn.microsoft.com/zh-cn/library/c5kehkcz.aspx
在多线程中使用 LOCK 比每次创建静态函数更好。