gpt4 book ai didi

c# - 一次写入多次读取的多线程是否需要 volatile?

转载 作者:太空宇宙 更新时间:2023-11-03 19:08:49 25 4
gpt4 key购买 nike

这是场景。我有一个将由多个线程 (ASP.NET) 访问的类,它可以从将结果存储在一次写入、多次读取的缓存中受益。此缓存对象是无法作为静态初始化程序的一部分执行的操作的结果,但必须等待第一次执行。所以我实现了一个简单的空检查,如下所示。我知道如果两个线程同时进行此检查,我将计算两次 ExpensiveCalculation,但这不是世界末日。我的问题是,由于优化或其他线程缓存,我是否需要担心静态 _cachedResult 仍被其他线程视为 null。一旦写入,对象只会被读取,所以我认为不需要全面锁定。

public class Bippi
{

private static ExpensiveCalculation _cachedResult;

public int DoSomething(Something arg)
{

// calculate only once. recalculating is not harmful, just wastes time.
if (_cachedResult == null);
_cachedResult = new ExpensiveCalculation(arg);


// additional work with both arg and the results of the precalculated
// values of _cachedResult.A, _cachedResult.B, and _cachedResult.C
int someResult = _cachedResult.A + _cachedResult.B + _cachedResult.C + arg.ChangableProp;
return someResult;

}

}

public class ExpensiveCalculation
{

public int A { get; private set; }
public int B { get; private set; }
public int C { get; private set; }

public ExpensiveCalculation(Something arg)
{
// arg is used to calculate A, B, and C
}

}

附加说明,这是在 .NET 4.0 应用程序中。

最佳答案

My question is, do I need to worry about the static _cachedResult still being seen as null by other threads due to optimizations or other thread caching.

是的,你知道。这是 volatile 存在的主要原因之一。

值得一提的是,无竞争锁增加的性能成本完全可以忽略不计,所以真的没有理由只是lock null 检查和资源生成,因为它几乎肯定不会导致任何性能问题,并使程序更容易推理。

最好的解决方案是完全避免这个问题,并使用专门设计用于解决您遇到的确切问题的更高级别的抽象。在这种情况下,这意味着 Lazy。您可以创建一个 Lazy 对象来定义如何创建您的昂贵资源,在您需要该对象的任何地方访问它,并且 Lazy 实现负责确保资源被创建不超过一次,并且它正确地暴露给请求所述资源的代码,并且它得到有效处理。

关于c# - 一次写入多次读取的多线程是否需要 volatile?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22947864/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com