Is the ternary operator (?:) thread safe in C#?

匿名 (未验证) 提交于 2019-12-03 08:42:37

问题:

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.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!