Skip to main content
 首页 » 编程设计

c#之是否加锁 : Parallel String Concatenation

2024年01月28日29soundcode

我正在从多个线程调用一个简单的字符串连接函数。我认为应该锁定它。做了很多带锁和不带锁的测试。它从未失败。

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

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 测试了以下变体 - 10000000 个周期。以毫秒为单位的时间是:

// 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

请您参考如下方法:

不,它不需要任何锁定结构。

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

我所说的“纯”是指一种方法:

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

(来源:Wikipedia: Pure Function)

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

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