代码之家  ›  专栏  ›  技术社区  ›  DooDoo

静态属性作为该类实例的线程安全考虑

  •  1
  • DooDoo  · 技术社区  · 7 年前

    public class BusinessClass
    {
        static BusinessClass myClass { get; set; }
        Repository repo;
    
        public BusinessClass()
        {
            if (repo == null)
                repo = new RepositoryClass();
        }
    
        public static BusinessClass Instance
        {
            get
            {
                if (myClass == null)
                    myClass = new BusinessClass();
                return myClass ;
            }
        }
    
        public void Update(Entity Item)
        {
            repo.Update(Item);
        }
    }
    

    我想用这个 BL

    BusinessClass.Instance.Update(Item);
    

    我的问题是:这段代码对线程安全有问题吗?两个人能在同一时间走到一起吗 Update 方法

    谢谢

    2 回复  |  直到 7 年前
        1
  •  4
  •   Aristos    7 年前

    如果使用asp.net窗体和asp.net会话,则该会话将锁定所有用户的整个调用, 因此,您不需要额外注意同步 那个

    相关问题:

    Does ASP.NET Web Forms prevent a double click submission?
    Trying to make Web Method Asynchronous
    Web app blocked while processing another web app on sharing same session
    What perfmon counters are useful for identifying ASP.NET bottlenecks?
    Replacing ASP.Net's session entirely

    第二种情况-本地线程。

    如果在同一调用中打开额外线程 ,则需要锁定对静态数据的操作。

    public class BusinessClass
    {
        private static readonly object oLock = new object();
    
        static BusinessClass myClass { get; set; } = null;
        Repository repo;
    
        public BusinessClass()
        {
            if (repo == null)
                repo = new RepositoryClass();
        }
    
        public static BusinessClass Instance
        {
            get
            {
                if myClass == null)
                {
                    lock (oLock)
                    {
                        if myClass == null)
                            myClass = new BusinessClass();
                    }
                }
                return myClass  
            }
        }
    
        public void Update(Entity Item)
        {
            repo.Update(Item);
        }
    }
    

    如果您希望在web garden上运行的web平台(同一站点的多个池)上,再次检查数据库或文件的全局更改,或系统模拟编辑可能更改的任何内容。。。并忽略会话。。。

    那你需要 mutex 同步所有呼叫。

    互斥

    多考虑多用户环境。

    想想这个场景。
    用户A和B,加载相同的页面、相同的数据,并且每一个都会更改它们。

    用户将保存每一个数据-不是在同一时刻-但有很多不同的时间。您记录的数据是最后保存的数据。其中一个用户将丢失其更改。

        2
  •  0
  •   sellotape    7 年前

    线程安全。以下是可能发生的情况的一个示例:

    线程1: if (myClass == null) <-接收true,因为它为null

    线程1: [temp1] = new BusinessClass(); [temp1] 存在 隐式地在线程1中

    <-接受真实,因为它仍然是真实的 无效的

    线程2: [temp2] = new BusinessClass(); <-- [temp2] 隐式地在线程2中

    线程2: myClass = [temp2];

    线程2: return myClass; <——返回创建的第二个实例

    myClass = [temp1];

    线程1: 返回myClass; <——返回创建的第一个实例

    Instance


    一种易于使用的线程安全直接替代方法是使用 Lazy<BusinessClass> myClass .