我有一个在大多数情况下都需要线程的应用程序。大多数时候我会遇到错误或错误的值,因为对象在每个线程执行之前就已更新。
您有什么建议可以使对象成为线程安全的,并确保对象对每个线程都是正确的吗?我应该让我的变量static
吗?
最佳答案
您应该做的第一件事是绘制您希望通过多线程解决的问题的Happens-Before 图。如果你不能画出你的设计,那就太复杂了。
例如,这是一个方法的发生前图,它接受两个整数数组并输出所有元素的总和。
一旦你有了 happens-before 图,就很容易看出什么事情必须先于其他事情发生,但更重要的是,它会告诉你什么事情不必先于其他事情发生。
在这个例子中,你可以同时得到 array1 和 array2 的总和。 您也可以同时获得 sum1 和 sum2,因为它们不相互依赖。 可以按任一顺序将总和添加到 TotalSum1,(但您需要锁定加法步骤,因为您不能与其他人同时进行加法)。
C# .net 4.0 具有许多用于并行编程的有用功能。
我推荐这本书Parallel Programming with Microsoft .Net -- 只需使用左侧的书签进行导航。它涵盖了 Loops、Tasks、Aggregation、Futures 和 Pipelines 的并行模式。
在上面的示例中,我将使用 Task1 获取 Array1,使用 Task2 获取 Array2,然后在这两个中我将使用内置于 Parallel.For 循环中的聚合模式来计算数组总和,我需要使用锁或 Interlocked.Add 来累积小计,然后等待任务完成并返回结果。
有用的模式:
- 任务
- 并行循环
- 生产者/消费者
- 管道
- 工作 list
- MapReduce
有用的工具:
- 任务并行库
- 并行.For
- 并行.Foreach,
- 任务
- Plinq
- 并发数据结构
- 并发队列
- 等等
- 锁定
- '锁定'关键字
- 监控(与“锁定”功能相同)
- 信号量
- 自旋锁
- 读/写锁
- 硬件原子操作
- 互锁.增量
- 互锁.Add
- Interlocked.CompareAndSwap
- 分配给机器字长变量,如 int
- 消息传递
- 理工学院
- 障碍
- 等等
基本上,首先了解您的问题,然后选择工具/模式来解决它。
关于c# - 如何在 C# 上使对象线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11623039/