可重入代码和局部变量

时间:2014-11-13 19:53:43

标签: c# .net multithreading thread-safety

我的方法如下:

private static string AmpRemove(string str)
{
    int index = str.IndexOf('&');
    if (index > 0)
        str = str.Substring(0, index);
    return str;
}

这里我试图从字符串中获取文本,直到找到&个字符。我的大四学生修改了这个方法

private static string AmpRemove(string str)
{
    if (str.IndexOf('&') > 0)
        str = str.Substring(0, str.IndexOf('&'));
    return str;
}

因此,不是存储index,而是计算它两次,他的推理是因为该方法将在多个线程中调用,所以index中可能存储无效值。

我对线程的理解是有限的,但我相信每个线程都有自己的堆栈,其中将推送参数strindex。我已经尝试过与他进行推理,这是一个可重入的代码,并且多线程无法修改此方法中的局部变量。

所以,我的问题是,我是否正确地假设缓存存储index是一个更好的解决方案,因为它不会涉及计算索引两次,因为它是局部变量和{ {1}}是方法的本地参数,多个线程无法修改/更改strstr

这是对的吗?

2 个答案:

答案 0 :(得分:8)

在给定代码的情况下无法修改

index,因为它是一个局部变量,从另一个线程调用的任何方法都是单独的调用,因此不共享局部变量。

但是,您不会控制string参数,因为它会被传入。这会使线程不安全......除了MSDN之外,string对象是不可变的。因此,您可以假设您传递的string在调用之间保持不变,并且是线程安全的。虽然您重新分配了str的值,但该参数未作为ref传递,因此仅重新分配本地指针,它修改调用者' s传入的变量。

因此,如所示,第一个代码是线程安全的。传入的类型的任何更改或传入的方式都不能立即被假定为线程安全。

答案 1 :(得分:2)

您的原始方法是线程安全的。但是:

  1. 重新分配方法变量可能会令人困惑,您只需返回子字符串: private static string AmpRemove(string str) { var index = str.IndexOf('&'); if (index > 0) { return str.Substring(0, index); } return str; }

  2. 如果'&'在索引0处,您的代码将返回整个字符串。是应该发生什么,或者它应该是索引> = 0?