【问题标题】:Reentrant code and local variables可重入代码和局部变量
【发布时间】:2014-11-13 19:53:42
【问题描述】:

我有一个类似的方法:

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会被推送。我已经尝试与他推理,这是一个可重入代码,并且多个线程无法修改此方法中的局部变量。

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

对吗?

【问题讨论】:

  • 是的,你是对的。缓存index 是错误的措辞。 index 只是方法的一个局部变量,不管你是否在线程环境中使用它。
  • 是的,我不知道如何才能对此做出一个好的回答,但是是的,你是对的......
  • 是的,你的学长应该休假。
  • @thumbmunkeys,感谢您的评论,我将缓存更改为存储。
  • @CriketerOnSO 只是扔在那里,以防你以前没见过它。干杯。

标签: c# .net multithreading thread-safety


【解决方案1】:

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

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

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

【讨论】:

  • 感谢您的回答,+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 处,您的代码将返回整个字符串。这是应该发生的事情,还是应该是 index >= 0?

【讨论】:

  • 谢谢,但是,如果& 是索引 0,那么我们需要整个字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-02
  • 1970-01-01
  • 1970-01-01
  • 2015-08-19
  • 1970-01-01
  • 1970-01-01
  • 2018-04-18
相关资源
最近更新 更多