三元运算符(?:)在C#中是线程安全的吗?
考虑以下两种选择,在三元运算符(?:)在C#中是线程安全的吗?,c#,thread-safety,ternary-operator,C#,Thread Safety,Ternary Operator,考虑以下两种选择,在currentPrice和100之间获得更高的数字 int price = currentPrice > 100 ? currentPrice : 100 int price = Math.Max(currentPrice, 100) 我提出这个问题是因为我在考虑一个上下文,在这个上下文中,currentPrice变量可以被其他线程编辑 在第一种情况下。。。price能否获得低于100的值 我在想以下几点: if (currentPrice > 100) {
currentPrice
和100
之间获得更高的数字
int price = currentPrice > 100 ? currentPrice : 100
int price = Math.Max(currentPrice, 100)
我提出这个问题是因为我在考虑一个上下文,在这个上下文中,currentPrice
变量可以被其他线程编辑
在第一种情况下。。。price
能否获得低于100
的值
我在想以下几点:
if (currentPrice > 100) {
//currentPrice is edited here.
price = currentPrice;
}
它不是线程安全的
?:
只是普通if
的快捷方式,因此您的if
示例相当于?
一个-如果此代码之外没有锁定,您可以获得低于100的价格。理论上,当前价格读取两次。一次用于比较,一次用于分配
实际上,编译器可能会缓存对变量的访问。我不知道C语言,但是在C++上,x86:< /p>
MOV AX, [currentPrice]
MOV BX, 100 ;cache the immediate
CMP AX, BX
JLE $1 ;if(currentPrice > 100){
MOV AX, BX
$1: ;}
MOV [BP+price], AX ;price is on the stack.
Java字节码中会发生相同的负载优化,除非currentPrice声明为volatile
因此,从理论上讲,这是可能发生的。实际上,在大多数平台上,它不会,但你不能指望它。不是C#方面的专家,但即使是var++也不是线程保存,因为may在汇编中从寄存器读/写转换为
三元运算符要复杂得多。它有3个部分,而每个部分都可以无限大(例如调用某个函数)。因此,很容易断定三元运算符不是线程安全的。正如其他人所说,它可能被缓存,但语言不需要它
如果需要无锁线程安全分配,可以使用。但是举个例子,我会选择更粗粒度的锁定策略。几分钟后的相反答案是:D@dotNETbeginner好的观察力。当我读到我的第一个答案时,我也想给我-10;恐怕x86不允许您
INC
rement内存位置,因此它将被转换为移动到注册表/增量/移动到内存组合。