7

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;
}
4

4 に答える 4

8

スレッドセーフではありません。

?:は normal の単なるショートカットなifので、ifサンプルは 1 つに相当し?ます。このコードの外側にロックがない場合、100 よりも低い価格を取得できます。

于 2012-10-13T06:33:55.370 に答える
3

理論的には、currentPriceは2回読み取られます。比較用に1回、割り当て用に1回。

実際には、コンパイラは変数へのアクセスをキャッシュする場合があります。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が揮発性であると宣言されていない限り、Javaバイトコードでも同じロードワンス最適化が行われます。

したがって、理論的には、それが発生する可能性があります。実際には、ほとんどのプラットフォームではそうではありませんが、それを当てにすることはできません。

于 2012-10-13T06:49:25.090 に答える
3

C#のスペシャリストではありませんが、var ++でさえ、アセンブリのレジスタへの読み取り/書き込みから変換される可能性があるため、スレッド保存ではありません。

三項演算子ははるかに複雑です。これには3つの部分がありますが、各部分は際限なく大きくなる可能性があります(たとえば、関数の呼び出し)。したがって、三項演算子はスレッドセーフではないと結論付けるのは非常に簡単です。

于 2012-10-13T06:51:25.257 に答える
1

他の人が述べたように、キャッシュされる可能性がありますが、言語では必要ありません。

ロックフリーのスレッドセーフ割り当てが必要な場合は、 Interlocked.CompareExchangeを使用できます。しかし、例を考えると、私はより粗粒度のロック戦略を採用したいと思います。

于 2012-10-13T07:08:28.587 に答える