【问题标题】:using static methods or instantiate the class?使用静态方法或实例化类?
【发布时间】:2010-07-28 09:53:39
【问题描述】:

最近我对在一个由数百个线程使用的类中使用静态方法产生了争议。 在我看来,“第一个”解决方案没有什么特别的好处,只是它更容易为班级客户使用,但有人告诉我这是非常糟糕的主意,我必须使用“第二个”解决方案。谁能给我清楚的解释为什么我错了? 非常感谢!

PS 假设字典是线程安全的。

class A
{
    static Dictionary<int, string> m_dic = new Dictionary<int, string>();
    public static string GetData1(int nKey)
    {
        return m_dic[nKey];
    }
    public string GetData2(int nKey)
    {
        return m_dic[nKey];
    }
}

//these func are called from threads...
void ThreadFunc1()
{
    print A.GetData1(1);
}

void ThreadFunc2()
{
    A a = new A();
    print a.GetData2(1);
}

问候, 狮子座

【问题讨论】:

    标签: c# multithreading static


    【解决方案1】:

    使用实例成员暗示(至少对我而言)实例本身有一些相关的东西——要么是它的状态,要么是可能它在被覆盖方面的行为方法(即“状态”是实例的执行时类型)。

    在这种情况下,这些都不正确 - 所以我认为创建实例是一种不好的风格,会导致误导性代码。

    【讨论】:

      【解决方案2】:

      如果线程需要访问线程安全的共享资源,静态类是完全可行的。所以你没有错。

      【讨论】:

        【解决方案3】:

        出于乔恩所说的所有原因,我肯定会使用静态方法,而且我想再添加一个。考虑以下在多线程环境中运行的代码。

        void ThreadFunc2() 
        { 
          var a = new A(); 
          if (a.GetData2(1) == "foo")
          {
            DoSomething(a.GetData2(1));
          }   
        } 
        

        一个毫无戒心的程序员创建了一个A 的新实例,并天真地对GetData2 进行了两次调用,它们相互依赖,认为不会出错,因为A 实例在其他任何地方都没有使用。但问题是不能保证GetData2 第二次返回相同的东西,因为另一个线程可能已经改变了该方法使用的静态字典。当您使用实例方法提取静态状态时,这完全不明显。

        我并不是说使用实例成员读取静态状态一定是错误的。我的意思是它有潜在导致问题,尤其是当暗示可以安全地从多个线程同时使用单独的对象实例时。

        【讨论】:

          【解决方案4】:

          C#中的静态数据可以与C++、Delphi等语言中的global variables进行比较。它们往往很糟糕,因为变量的内存是在应用程序启动时分配的,只有在应用程序结束时才释放。它们被认为是不好的,因为它们可以从代码中的任何位置进行修改。
          当然,你使用静态方法访问静态数据,但我建议你将静态数据设为私有,这样只有类本身才能通过静态方法修改数据。然后整个数据变成singleton
          顺便说一句,你假设它是线程安全的,但你最好确保它是线程安全的。
          关于通过实例调用静态方法。如果您需要该实例来执行其他任务,这是有道理的,但否则会浪费一点资源。这并没有错,除非某些开发人员将方法从静态更改为非静态,或者他们添加了具有相同名称和相似参数的非静态方法。从实例调用静态方法也会增加混乱,因为它使方法不清楚该方法对类本身的数据没有任何作用。

          【讨论】:

          • >>顺便说一句,你假设它是线程安全的,但你最好确保它是线程安全的。我正在使用线程保存版本 - 所以不用担心 :)
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-04-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-22
          • 2018-09-10
          • 2015-06-26
          相关资源
          最近更新 更多