考虑以下两种方法,在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;
}
答案 0 :(得分:8)
这不是线程安全的。
?:
只是正常if
的快捷方式,因此您的if
样本相当于?
一个 - 如果外面没有锁定,您可以获得低于100的价格这段代码。
答案 1 :(得分:3)
理论上,currentPrice被读取两次。一旦进行比较,一次进行分配。
实际上,编译器可以缓存对变量的访问。我不知道C#,但是在x86上的C ++中:
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.
除非currentPrice被声明为volatile,否则Java字节码中会发生相同的一次加载优化。
所以,从理论上讲,它可能会发生。在实践中,在大多数平台上,它不会,但你不能指望它。
答案 2 :(得分:3)
不是C#的专家,但即使var ++也不是线程保存,因为可能会从汇编中的读取/写入转换为写入。
三元运算符要复杂得多。它有3个部分,而每个部分可以无穷大(例如调用某个功能)。因此,很容易得出结论,三元运算符不是线程安全的。
答案 3 :(得分:1)
正如其他人所说,它可能会被缓存,但语言不需要它。
如果您需要无锁线程安全分配,可以使用Interlocked.CompareExchange。但是举个例子,我会采用更粗粒度的锁定策略。