是否有使方法线程安全的总体规则/指南?我知道可能有一百万个一次性的情况,但一般来说呢?就这么简单吗?
是这样吗?这也适用于静态方法吗?
@Cybis 提供的一个答案是:
局部变量不能在线程之间共享,因为每个线程都有自己的堆栈。
静态方法也是这样吗?
如果一个方法被传递一个引用对象,这会破坏线程安全吗?我做了一些研究,关于某些情况有很多,但我希望能够通过使用一些规则来定义要遵循的准则,以确保方法是线程安全的。
所以,我想我的最终问题是:“是否有定义线程安全方法的规则的简短列表?如果有,它们是什么?”
编辑 这里提出了很多好的观点。我认为这个问题的真正答案是:“没有简单的规则来确保线程安全。” 凉爽的。美好的。但 总的来说, 我认为接受的答案提供了一个很好的简短总结。总是有例外。随它吧。我可以忍受这一点。
如果一个方法(实例或静态)仅引用该方法范围内的变量,那么它是线程安全的,因为每个线程都有自己的堆栈:
在这种情况下,多个线程可以ThreadSafeMethod同时调用而不会出现问题。
ThreadSafeMethod
public class Thing { public int ThreadSafeMethod(string parameter1) { int number; // each thread will have its own variable for number. number = parameter1.Length; return number; } }
如果该方法调用仅引用局部范围变量的其他类方法,这也是正确的:
public class Thing { public int ThreadSafeMethod(string parameter1) { int number; number = this.GetLength(parameter1); return number; } private int GetLength(string value) { int length = value.Length; return length; } }
如果一个方法访问任何(对象状态)属性或字段(实例或静态),那么您需要使用锁来确保这些值不会被不同的线程修改:
public class Thing { private string someValue; // all threads will read and write to this same field value public int NonThreadSafeMethod(string parameter1) { this.someValue = parameter1; int number; // Since access to someValue is not synchronised by the class, a separate thread // could have changed its value between this thread setting its value at the start // of the method and this line reading its value. number = this.someValue.Length; return number; } }
您应该知道,传入方法的任何参数(不是结构或不可变的)都可能被方法范围之外的另一个线程改变。
为了确保正确的并发性,您需要使用锁定。
有关详细信息,请参阅lock 语句 C# 参考和ReadWriterLockSlim。
lock 主要用于一次提供一个功能, ReadWriterLockSlim如果您需要多个读取器和单个写入器,则很有用。
ReadWriterLockSlim