C#:HashSet的易失性读写 [英] C#: volatile reads and writes of HashSet
问题描述
我有一堂课
public class Checker
{
private HashSet<int> _hs = new HashSet<int>();
public bool Check(int a)
{
return Volatile.Read(ref _hs).Contains(a);
}
public void Update(IEnumerable<int> items)
{
Volatile.Write(ref _hs, new HashSet<int>(items));
}
}
从多个线程中经常调用
方法 Check
.从单个线程中调用方法 Update
,该线程监视某些源(数据库,http服务等).这种 Volatile.Read/Volatile.Write
使用模式正确吗?
Method Check
is called from multiple threads quite often. Method Update
is called from a single thread which monitors some source (database, http service etc.). Is this pattern of Volatile.Read / Volatile.Write
usage correct?
推荐答案
如果您的意思是将 Check
始终使用该字段的最新版本",那么可以,这将是波动性的结果-交换整个引用比持续同步要便宜得多(.NET确保您不会有撕裂的引用,因此保证了引用交换是原子的).
If you mean "will Check
always use the most up to date version of the field", then yes, as a side-effect of volatility this will be the case - and swapping the entire reference is much cheaper than constantly synchronizing (.NET ensures you can't have a torn reference so the reference swap is guaranteed to be atomic).
注意:这种情况下的线程安全性严格取决于散列集在创建和引用交换后不会发生突变的事实,这在代码中会发生问题中.
Note: the thread-safety in this scenario is strictly dependent on the fact that the hash-set is not mutated after it has been created and the reference swapped, which is what happens in the code in the question.
但是,通过将字段声明为 volatile
:
You can get the same result more conveniently, though, by declaring the field as volatile
:
public class Checker
{
private volatile HashSet<int> _hs = new HashSet<int>();
public bool Check(int a) => _hs.Contains(a);
public void Update(IEnumerable<int> items) => _hs = new HashSet<int>(items);
}
这篇关于C#:HashSet的易失性读写的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!