开发者

C# Thread Safety Question

How do I make code like this thread safe?

public static class Converter
{
    public static string ConvertNameToNickname(string name)
    {
        if (name.Equals("John"))
        {
            return "Johnathon";
        }

        return name;
    }
}

Or is it already thread safe since "name" is a local variable? I just want to make sure if ConvertNameToNickname was called by two different threads the name it was evaluating wasn't being stepped on by other threads.

<--edit-->

Ok some of these answers have been pretty helpful but I still haven't ferreted out the answer I was looking for so let me modify it a bit and ask the same question. How would I make this code thread safe given a mutable-type parameter? Or is it even possible? If I throw a lock{} around the entire method body (shown in the example 2) is it still possible for the instance variable "name" to be modified before we enter the lock statement block?

public static class Converter
{
    public static string ConvertNameToNickname(StringBuilder name)
    {
        if (name.ToString().Equals("John"))
        {
            return "Johnathon";
        }

        return name;
    }
}

Example 2:

开发者_如何学Goprivate static readonly object _lockObject = new object();

public static class Converter
{
    public static string ConvertNameToNickname(StringBuilder name)
    {
        lock(_lockObject)
        {
            if (name.ToString().Equals("John"))
            {
                return "Johnathon";
            }

            return name;
        }
    }
}


Or is it already thread safe since "name" is a local variable?

Close. It is threadsafe, but not because of the local variables. However, since string in .NET is immutable, this is thread safe. The key to being thread safe without synchronization is always working with immutable types. With mutable types, even methods like .Equals may not be thread safe.

Were string a mutable class, this would not necessarily be thread safe.


Edit:

Ok some of these answers have been pretty helpful but I still haven't ferreted out the answer I was looking for so let me modify it a bit and ask the same question. How would I make this code thread safe given a mutable-type parameter? Or is it even possible?

Yes, it is potentially possible. However, it requires synchronization of some form to be correct. Using a lock is one option.

If I throw a lock{} around the entire method body (shown in the example 2) is it still possible for the instance variable "name" to be modified before we enter the lock statement block?

Unfortunately, it is. The lock prevents this code from being called simulatenously from two different threads. In essence, you're making this specific use of "name" thread safe. However, if "name" is used elsewhere in your program, it's still possible that it can be modified by some other function while being used within your lock. This could lead to a subtle race condition.

Thread-safety is tough to get right. The best option for thread-safe usage of mutable types is usually to provide your own, thread safe types - where the type itself handles all of its required synchronization internally, and the public API is completely thread safe. This is the only way to guarantee that nobody else will "mess with" your data, even if you're locking around the usage.

This is where immutable types come into play - they eliminate all of these worries, since their state can't be changed once created. Anybody can use them, and construct more, without risk to the type itself.


Yes, it's already thread safe since "name" is a local variable assigned to an immutable object.

Local parameters are passed by value, so a copy of the value/reference is always made, as opposed to a ref parameter in which case you might have concurrency issues if it was a reference to a field.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜