C# 合并运算符的原子性
我今天在我们的代码库中遇到了一些单例代码,我不确定以下内容是否是线程安全的:
public static IContentStructure Sentence{
get {
return _sentence ?? (_sentence = new Sentence());
}
}
此语句相当于:
if (_sentence != null) {
return _sentence;
}
else {
return (_sentence = new Sentence());
}
我相信??只是一个编译器技巧,生成的代码仍然不是原子的。换句话说,两个或多个线程在将 _sentence 设置为新 Sentence 并返回它之前可能会发现 _sentence 为 null。
为了保证原子性,我们必须锁定那段代码:
public static IContentStructure Sentence{
get {
lock (_sentence) { return _sentence ?? (_sentence = new Sentence()); }
}
}
这一切都正确吗?
I ran into some singleton code today in our codebase and I wasn't sure if the following was thread-safe:
public static IContentStructure Sentence{
get {
return _sentence ?? (_sentence = new Sentence());
}
}
This statement is equivalent to:
if (_sentence != null) {
return _sentence;
}
else {
return (_sentence = new Sentence());
}
I believe that ?? is just a compiler trick and that the resulting code is still NOT atomic. In other words, two or more threads could find _sentence to be null before setting _sentence to a new Sentence and returning it.
To guarantee atomicity, we'd have to lock that bit of code:
public static IContentStructure Sentence{
get {
lock (_sentence) { return _sentence ?? (_sentence = new Sentence()); }
}
}
Is that all correct?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的代码库中是否有这样的混淆代码?这段代码做了同样的事情:
并且可读性提高了一千倍。
你是对的。 C# 对原子性做出以下保证:
空合并运算符不在该保证列表中。
天哪,不。那立刻就崩溃了!
正确的做法是:
Lazy
类。Do you have such obfuscated code throughout your codebase? This code does the same thing:
and is about a thousand times easier to read.
You are correct. C# makes the following guarantees of atomicity:
The null coalescing operator is not on that list of guarantees.
Good heavens no. That crashes immediately!
The correct thing to do is one of:
Lazy<T>
class.你是对的;它根本不是线程安全的。
You are correct; it's not at all thread-safe.
您可以将 Interlocked.CompareExchange 与
null
一起使用获得一个??
式的原子操作。You can use Interlocked.CompareExchange with
null
to get a??
-esque operation that is atomic.