可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Consider the following two alternatives of getting the higher number between currentPrice
and 100
...
int price = currentPrice > 100 ? currentPrice : 100 int price = Math.Max(currentPrice, 100)
I raised this question because I was thinking about a context where the currentPrice
variable could be edited by other threads.
In the first case... could price
obtain a value lower than 100
?
I'm thinking about the following:
if (currentPrice > 100) { //currentPrice is edited here. price = currentPrice; }
回答1:
It is not threadsafe.
?:
is just shortcut for normal if
, so your if
sample is equivalent to ?
one - you can get price lower than 100 if there is no locking outside this code.
回答2:
Not a specialist in C#, but even var++ is not thread save, since may translated to from reading into/writing from register in assembly.
Ternary operator is far more complicated. It has 3 parts, while each part can be endlessly big (e.g. call to some function). Therefore, it's pretty easy to conclude that ternary operator is not thread safe.
回答3:
In theory, currentPrice is read twice. Once for comparison, once for assignment.
In practice, the compiler may cache the access to the variable. I don't know about C# but in C++ on x86:
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.
The same load-once optimisation happens in Java bytecode unless currentPrice is declared volatile.
So, in theory, it can happen. In practice, on most platforms, it won't, but you cannot count on that.
回答4:
As stated by others, it might be cached but the language does not require it.
You can use Interlocked.CompareExchange if you need lock-free threadsafe assignments. But given the example, I'd go for a more coarse grained locking strategy.