Pat*_*ski 4 c# concurrency .net-core
假设我们有:
var dictionary = new ConcurrentDictionary<string, Lazy<Heavy>>();
Run Code Online (Sandbox Code Playgroud)
实例化Heavy非常耗费资源.我们考虑一下这段代码:
return dictionary.GetOrAdd("key", key =>
{
return new Lazy<Heavy>(() =>
{
return Instantiate();
});
}).Value;
Run Code Online (Sandbox Code Playgroud)
该方法Instantiate()当然返回一个类型的实例Heavy.
对于给定的密钥,是否100%保证该方法最多Instantiate()只能被调用一次?
有些人声称拥有多个线程,我们只能创建多个实例Lazy<Heavy>,这非常便宜.实际方法Instantiate()最多只能调用一次.
我个人有一种印象,认为这是错误的.真相是什么?
Instantiate确实只会执行一次.文件GetOrAdd说:
如果在不同的线程上同时调用GetOrAdd,可能会多次调用addValueFactory,但是对于每个调用,它的键/值对可能不会添加到字典中.
这意味着:即使addValueFactory多次运行 - 实际上只有一个返回值会被添加到字典中并从GetOrAdd调用中返回.因此,如果两个线程GetOrAdd同时使用相同的密钥调用- Lazy<Heavy>创建了2个实例,但只有1个实例被添加到字典并从两个 GetOrAdd调用返回,则另一个被丢弃(因此,即使工厂已经运行 - 它也不会这个工厂提供的平均值是最终返回的GetOrAdd).因为你调用.Value了结果GetOrAdd- 你总是在单个实例上调用它Lazy<Heavy>,所以Instantiate总是最多运行一次.
| 归档时间: |
|
| 查看次数: |
206 次 |
| 最近记录: |