是否锁定:并行字符串连接

时间:2013-07-06 18:37:54

标签: c# .net locking multitasking string-concatenation

我从多个线程调用一个简单的字符串连接函数。我认为应该锁定它。用锁或无锁进行了许多测试。它永远不会失败。

我的问题是:是否必须锁定字符串连接?

private readonly object idLock = new object();

private string GetId(string input1, string input2, string input3)
{
    lock (idLock)
        return string.Format("{0}; {1}; {2}", input1, input2, input3);
}

我用PLINQ测试了以下变体--1000000个循环。以毫秒为单位的时间是:

// Time 5446
lock (idLock)
    return string.Format("{0}; {1}; {2}", input1, input2, input3);

// Time 3728
lock (idLock)
    return input1 + "; " + input2 + "; " + input3;

// Time 953
return string.Format("{0}; {1}; {2}", input1, input2, input3);

// Time 652
return input1 + "; " + input2 + "; " + input3;

完整的测试代码在这里:Test Parallel String Concatenation

2 个答案:

答案 0 :(得分:3)

不,它不必具有任何锁定结构。

任何纯方法在多线程环境中都能正常运行。

纯粹"我的意思是一种方法:

  • 在给定相同参数值的情况下,函数始终评估相同的结果值。函数结果值不能依赖于程序执行过程中或程序的不同执行之间可能发生变化的任何隐藏信息或状态,也不依赖于I / O设备的任何外部输入。
  • 评估结果不会导致任何语义上可观察到的副作用或输出,例如可变对象的突变或输出到I / O设备。

(来源:Wikipedia: Pure Function

在您的情况下,字符串连接本身在多线程环境中很好,并且不需要任何锁定构造。

但是,如果你要连接从其他线程可以更改的字段或属性中读取的字符串,然后,则需要锁定或类似,以确保系统的稳定性,但你问题中的示例代码,没有。

答案 1 :(得分:3)

  

我的问题是:是否必须锁定字符串连接?

不,你不需要任何锁定。 MSDN声明System.String 线程安全(它的方法也是如此,包括Format方法)。

这并不奇怪,因为.Net字符串是不可变的,这意味着它的值在创建后无法更改。不可变类型本质上是线程安全的,因为它们的值不能被一个线程更改而另一个线程也访问它。如果您的输入参数是 mutable 的任何其他引用类型,那么您可能会遇到潜在的问题。