问题描述
是否有什么让一个方法是线程安全的总体规则/指南?据我所知,大概有一百万的一次性情况,但对于一般的?难道这个简单的?
Are there overall rules/guidelines for what makes a method thread-safe? I understand that there are probably a million one-off situations, but what about in general? Is it this simple?
- 如果一个方法只访问本地变量,它是线程安全的。
是不是这样?这是否适用于静态方法呢?
Is that it? Does that apply for static methods as well?
一个答案,@Cybis提供的是:局部变量不能线程之间,因为每个线程都有自己的堆栈共享。是静态方法呢?
One answer, provided by @Cybis, was: "Local variables cannot be shared among threads because each thread gets its own stack." Is that the case for static methods as well?
如果一个方法传递一个参照对象,这是否破线程安全?我做了一些研究,有很多在那里有关某些情况下,但我希望能够来定义,用短短的规则,指引,以确保一个方法是线程安全的。
If a method is passed a reference object, does that break thread safety? I've done some research, and there is a lot out there about certain cases, but I was hoping to be able to define, by using just a few rules, guidelines to follow to make sure a method is thread safe.
所以,我想我最终的问题是:是否存在的定义线程安全的方法如果是这样,它们是什么规则的短名单?
So, I guess my ultimate question is: "Is there a short list of rules that define a thread-safe method? If so, what are they?"
**编辑**
有一个很大的优点已此处进行。我认为真正的答案是:有没有简单的规则,以保证线程安全。凉。精细。但是的一般的我想接受的答案提供了一个良好的,简短的摘要。总有例外。就这样吧。我可以忍受。
A lot of good points have been made here. I think the real answer to this question is: "There are no simple rules to ensure thread safety." Cool. Fine. But in general I think the accepted answer provides a good, short summary. There are always exceptions. So be it. I can live with that.
推荐答案
如果一个方法(实例或静态)只引用该法范围内的变量那么它是线程安全的,因为每个线程都有自己的堆栈:
If a method (instance or static) only references variables scoped within that method then it is thread safe because each thread has its own stack:
在这种情况下,多个线程可以同时调用ThreadSafeMethod没有问题。
In this instance, multiple threads could call ThreadSafeMethod concurrently without issue.
public class Thing
{
public int ThreadSafeMethod(string parameter1)
{
int number; // each thread will have its own variable for number.
number = parameter1.Length;
return number;
}
}
这也是真,如果该方法调用其他类的方法只引用本地范围的变量:
This is also true if the method calls other class method which only reference locally scoped variables:
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;
}
}
如果一个方法访问的任何(对象状态)的属性或字段(实例或静态),那么你需要使用锁,以确保价值不被不同的线程修改。
If a method accesses any (object state) properties or fields (instance or static) then you need to use locks to ensure that the values are not modified by a different thread.
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;
}
}
您应该知道,在传递给方法的任何参数不属于任何一个结构或不可改变可以由法范围之外的另一个线程突变。
You should be aware that any parameters passed in to the method which are not either a struct or immutable could be mutated by another thread outside the scope of the method.
要确保正确的并发你需要使用锁定。
To ensure proper concurrency you need to use locking.
有关详细信息,请参见和ReadWriterLockSlim.
for further information see lock statement C# reference and ReadWriterLockSlim.
锁是在同一时间的功能设置一个最有用,ReadWriterLockSlim如果需要多个读者和作家单是很有用的。
lock is mostly useful for providing one at a time functionality, ReadWriterLockSlim is useful if you need multiple readers and single writers.
这篇关于是什么让一个方法线程安全的吗?什么是规则?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!