参数线程安全吗?

时间:2017-07-07 14:58:35

标签: c# multithreading parameters thread-safety

我已经阅读了很多关于这个主题的帖子,但是当从多个线程调用C#处理方法中的参数时,我仍然有点模糊。

我有一系列需要从大约60多个线程调用的实用程序方法。这是一个每天为大约20,000-30,000名患者下载患者数据的过程。在大多数情况下,方法看起来像这样。


    Public Static SomeClass
    {
        public static string StringToSQLBool(string s)
        {
           if (s.Trim() == "")
           {
              return "Null";
           }
           else
           {
              if (s.ToLower() == "true")
              {
                 return "1";
              }
              {
                 return "0";
              }
           }
        }

        public static string DateToSQLAnsiStr(string ADate)
        {
            try
            {
               if (ADate.Trim() != "")
               {
                  DateTime d = Convert.ToDateTime(ADate);
                  return "{d '" + d.Year.ToString() + "-" +
                          d.Month.ToString().PadLeft(2, '0') + "-" +
                          d.Day.ToString().PadLeft(2, '0') + "'}";
               }
               else
               {
                  return "Null";
               }
            }
            catch
            {
               return "Null";
            }
        }
    }

据我所知,只要参数在调用线程的单数方法中使用,就会被认为是安全的。

这些线程是否安全而不锁定?

3 个答案:

答案 0 :(得分:3)

在线程中尝试操纵(或在一个中操作并在另一个中访问)相同的对象 时,线程是一个问题。通过访问对象的“名称”无关紧要。

使用术语“变量”来讨论类成员是一种不太理想的方式,特别是在上下文中,引用字段。这是关键的区别:局部变量,包括参数,一次只能由两个线程 1 访问。

逐字回答问题:“参数始终是线程安全的”,尽管它们评估为的对象可能不是。

但是,在示例代码中,仅使用 不可变对象 2

String +运算符返回一个 new 字符串,它是两者的串联,这是新的String结果,它被重新赋值给local(参数)变量。同样的逻辑适用于DateTime。

因此,发布的代码存在 no 线程问题;因为不管局部变量或参数如何,都没有相同对象的共享操作(或操作和访问)。

1 对线程绑定变量(包括参数)的访问通常必须在线程上下文中视为 field 访问。这是因为C#编译器在幕后合成/创建一个隐藏对象,然后对其进行操作以存储闭包状态。

2 如果某个对象在创建后无法操作,则会将其视为不可变类型,并且本质上是线程安全的。字符串属于这一类。 (只有在完全构造对象后才能保证不可变对象的线程安全。)

答案 1 :(得分:2)

对来自不同线程的方法的每次调用都有自己的堆栈。传递给方法的值类型存储在堆栈中。传递给方法的引用类型的指针存储在堆栈中。无论哪种方式,它都在堆栈上。

因为每个线程都有自己的堆栈,所以多次调用来自不同线程的方法不会覆盖"#34;覆盖"彼此'参数。

  

据我所知,只要参数在调用线程的单数方法中使用,就会被认为是安全的。

有一种倾向,像律师一样选择这样的陈述(特别是因为它涉及听起来像医疗记录。)你的理解是正确的。

我并不是说像律师一样挑选问题是错误的。细节很重要。但是你非常清楚地问了你的问题所以我明白你的意思。

我怎么说这个没有听起来有点光顾,因为你可能是一个非常有经验的程序员,这恰好是你第一次使用.NET专门处理多线程。请小心。我想到医疗记录是错误的人,声称被拒绝,或者因为线程错误而不小心接受化疗或性别重新分配,我感到非常震惊。我认为在这种情况下,社区应该非常积极地协助您处理所有多线程问题。

答案 2 :(得分:0)

标题中问题的答案是“可能;这取决于他们的类型。”

  • 值类型:是
  • 参考类型:
    • 不可变对象:是
    • 普通对象:否