三元运算符(?:)在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内存位置,因此它将被转换为移动到注册表/增量/移动到内存组合。