【问题标题】:Need to synchronize two classes需要同步两个类
【发布时间】:2015-04-21 19:17:24
【问题描述】:

我有两个类 A 和 B。两者都互相调用并拥有自己的锁。我在一种特定情况下陷入僵局。这是示例代码。

class A : Interface1, Interface2
{
    private B _bInstance = new B(); 
    private object _aSync = new object();

    private static A Instance;
    private A(){}

    public GetInstance()
    {
        if (Instance == null)  Instance = new A();
        return Instance;
    }

    void Method1()
    {
        lock(_aSync)
        {
            _bInstance.Method1();
        }
    }

    void WriteData()
    {
        lock (_aSync)
        {
            WriteToFile();
        }
    }
}

class B
{
    private object _bSync = new object();

    void Method1()
    {
        lock (_bSync)
        {
            // Have some code here which need to protect my
            // member variables.
            A.GetInstance.WriteData();
        }
    }

    void OneSecondTimerEvent()
    {
        lock (_bSync)
        {
            // Have some code here which need to protect my
            // member variables.
            A.GetInstance.WriteData();
        }
    }
}

如果在执行A.Method1() 时触发了一秒计时器,我如何同步OneSecondTimerEvent()

【问题讨论】:

  • 我强烈建议不要使用循环依赖——尤其是在多线程环境中。

标签: c# multithreading


【解决方案1】:

是的,您的代码显示了 deadlock 的规范示例 - 2 个资源等待彼此继续。

要解决,您可以:

  • 手动订购lock 语句(即,如果 A 已经拥有锁,则 B 永远不会获取额外的锁),
  • 作用域只锁定每个类的内部状态,从不嵌套锁定。在这种情况下,有时您需要复制状态来调用外部方法。
  • 使用允许此类嵌套的其他同步原语/构造(即读写器锁)。

【讨论】:

    【解决方案2】:

    与其尝试解决这个特定的死锁问题(顺便说一句,这是以不一致的顺序锁定事物的典型结果),我强烈建议在 A 和 B 之间设计更好的关系。事实上你必须使用静态实现循环依赖的实例应该是您做错了什么的重要线索。也许 A 和 B 应该引用第三类 C,它只负责锁定和写入数据? (虽然没有更多的上下文很难说)。

    【讨论】:

      猜你喜欢
      • 2016-09-01
      • 1970-01-01
      • 2012-11-24
      • 2017-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多