2010-07-28 52 views
1

最近我有一个关于在数百个线程使用的类中使用静态方法的争议。 在我看来,“第一”解决方案没有特别的好处,除了它更容易用于课堂的客户,但我被告知这是一个非常糟糕的主意,我不得不使用“第二”解决方案。任何人都可以给我清楚的解释,为什么我错了? 非常感谢!使用静态方法或实例化类?

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); 
} 

问候, 列昂尼德

回答

3

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

5

使用实例成员意味着(对我来说,至少)是有相关的有关实例本身的东西 - 无论它的状态,或可能其在重载方法方面的行为(即“状态”是实例的执行时间类型)。

在这种情况下,这些都不是真的 - 所以我会将视图创建为不良风格,导致误导性代码。

1

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

+0

>>顺便说一句,你认为它是线程安全的,但你最好确保它是线程安全的。 即时通讯使用线程保存版本 - 所以不要担心:) – Leonid 2010-07-28 14:46:18

2

我肯定会去静态方法的所有原因乔恩说,再加上我想补充一个。考虑在多线程环境中运行的以下代码。

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

不知情的程序员创建的A一个新实例,并天真地发出两次呼叫GetData2是互相依赖的思想,由于A例如不能用于其他地方没有什么可能出错。但问题是没有保证GetData2将第二次返回相同的东西,因为另一个线程可能已经改变了该方法使用的静态字典。当您使用实例方法提取静态时,这完全不明显。

我并不是说使用实例成员来读取静态就一定是错误的。我在说的是它有潜在的引起问题,特别是当暗示可以安全地从多个线程同时使用单独的对象实例时。

相关问题