线程安全类库设计

时间:2009-08-10 13:15:48

标签: c# oop

我正在开发一个类库,并选择了一条带有我设计的路径,以便稍微简化实现和线程安全,但我想知道是否有更好的方法。

一个简短的背景是我在类库中有一个多线程启发式算法,一旦设置了场景,就应该尝试解决它。但是我显然希望它是线程安全的,如果有人在解决这个问题时对任何事情进行了更改,导致崩溃或错误。

我得到的当前方法是,如果我有一个A类,那么我为每个A实例创建一个数字InternalA实例。 InternalA具有A类中的许多重要属性,但是在库外部是无法访问的。

这样做的缺点是,如果我希望扩展决策逻辑(或实际让某人在库外执行此操作)那么这意味着我需要更改InternalA中的代码(或提供某种委托功能) )。

这听起来像是正确的做法吗?

4 个答案:

答案 0 :(得分:2)

很难真正说出来 - 但是我可以说如果你能让一切变得一成不变,你的生活就会轻松得多。看看函数式语言如何处理不可变数据结构和集合。您拥有的共享可变数据越少,简单的线程就越多。

答案 1 :(得分:2)

为什么不呢? 创建通用类,接受2个成员类(例如,锁定/解锁) - 这样您就可以提供

  • Threadsafe impl(implmenetation可以使用Monitor.Enter / Exit里面)
  • 系统范围的安全impl(使用Mutex)
  • 不安全,但很快(使用空impl)。

答案 2 :(得分:1)

我取得一些成功的另一种方法是使用接口来实现功能分离。这种方法的成本是你最终会重复某些字段,因为每个接口都要求与其他字段完全分离。

在我的情况下,我有2个线程需要传递一组可能很大并且需要尽可能少的垃圾收集的数据。即我只想将更改信息从第一阶段传递到第二阶段。然后将第一个流程作为下一个工作单元。

这是通过使用更改缓冲区将更改从一个接口传递到下一个接口来实现的。

这允许一个线程在一个接口上工作,进行所有更改,然后发布一个包含其他接口(线程)在工作之前需要应用的更改的结构。

通过执行此操作您有一个双缓冲区...(线程1生成更改报告,而线程2使用上一个报告)。如果添加更多接口(和线程),则看起来有一些工作脉冲在线程中移动。

这是基于我的研究,我毫不怀疑现在有更好的方法。

我提出这个问题的目的是通过设计竞争条件来避免绝大多数代码中的锁定。另一个主要考虑因素是垃圾收集的性能 - 这可能不是你的问题。

这种方式一切都很好,直到您需要线程之间的复杂交互...然后您会发现您开始强制缓冲结构的布局以便重用以绕过继承,而继承又会产生维护开销。

答案 3 :(得分:0)

关于帮助问题的更多信息...

我正在使用的启发式方法是解决TSP问题。什么在每个开始时发生 计算是克隆形成问题的所有方面(销售人员/访问的地方) 所以它们不受跨线程的影响。

这意味着每个线程都可以更改数据(例如销售人员剩余的库存等),因为有一个数字 随着事情的进展,在计算过程中发生变化的值。我非常喜欢做的是允许 对于一个简单的例子,使用库来检查,例如HasSufficientStock()。

然而,目前仍然难以在线程和材料之间添加进一步的保护,一些更简单/轻量级 类我将它们转换为这些内部类,这些是实际使用和克隆的东西。

例如

class A
{
   public double Stock { get; }

   // Processing and cloning actually works using these InternalA's
   internal InternalA ConvertToInternal() {}
}

internal class InternalA : ICloneable
{
   public double Stock { get; set; }

   public bool HasSufficientStock() {}
}
相关问题