代码改变世界

在多线程中使用静态方法是否有线程安全问题(转载)

2017-05-18 11:41  追忆似水流年  阅读(282)  评论(0编辑  收藏  举报

原文出处:http://www.cnblogs.com/tiancai/p/5417767.html

另外一篇描述:https://zhidao.baidu.com/question/394984299357804085.html

类的成员分为两类,静态成员(static member)和实例成员(instance member)。静态成员属于类,实例成员则属于对象,即类的实例。

     简单讨论一下在一个类中使用静态字段(static field)和静态方法(static method)是否会有线程安全问题。 

     我们在知道, 静态字段(static field)和静态方法(static method)的调用是通过类来调用。静态方法不对特定的实例操作,只能访问静态成员。实例方法可对特定的实例操作,既能访问静态成员,也能访问实例成员。

     那么,在多线程中使用静态方法是否有线程安全问题?这要看静态方法是否引起线程安全问题,要看在静态方法中是否使用了静态成员。

     因为,在多线程中使用同一个静态方法时,每个线程使用各自的实例字段(instance field)的副本,而共享一个静态字段(static field)。所以说,如果该静态方法不去操作一个静态成员,只在方法内部使用实例字段(instance field),不会引起安全性问题。但是,如果该静态方法操作了一个静态字段,则需要静态方法中采用互斥访问的方式进行安全处理。
    
     举个简单的例子,我们使用的Console.WriteLine();中WriteLine()是Console类的静态方法。

     对于ASP.NET, 多个客户端访问服务器端, 这是一个多线程的例子.只要理解了原因,我们可以在三层架构中的数据访问层中放心使用静态方法(static method)来访问数据库.

先看一个类:
public class Test
{
   public static String hello(String str)
   {
       String tmp = "";
       tmp = tmp + str;
       return tmp;
   }
}
hello方法会不会有多线程安全问题呢?没有!
静态方法如果没有使用静态变量,则没有线程安全问题。
为什么呢?因为静态方法内声明的变量,每个线程调用时,都会新创建一份,而不会共用一个存储单元。比如这里的tmp,每个线程都会创建自己的一份,因此不会有线程安全问题。
注意:静态变量,由于是在类加载时占用一个存储区,每个线程都是共用这个存储区的,所以如果在静态方法里使用了静态变量,这就会有线程安全问题!