2012-10-13 18 views
7

Rozważmy następujące dwie alternatywy coraz większą liczbę pomiędzy currentPrice i 100 ...Czy wątek trojański (? :) wątek jest bezpieczny w C#?

int price = currentPrice > 100 ? currentPrice : 100 

int price = Math.Max(currentPrice, 100) 

Podniosłem to pytanie, bo myślał o kontekście, w którym zmienna currentPrice mogą być edytowane przez innych wątków.

W pierwszym przypadku ... czy price może uzyskać wartość niższą niż 100?

myślę o następujące elementy:

if (currentPrice > 100) { 
    //currentPrice is edited here. 
    price = currentPrice; 
} 

Odpowiedz

8

Nie wątkowo.

?: jest tylko skrót do normalnego if, więc próbka if jest równoważna ? jeden - można dostać cenę niższą niż 100 jeśli nie ma zamek na zewnątrz tego kodu.

+0

Odmowna odpowiedź w kilka minut? : D – dotNETbeginner

+0

@dotNETbeginner :) Dobra obserwacja. kiedy przeczytałem swoją pierwszą odpowiedź, chciałem dać mi również -10. –

3

Teoretycznie currentPrice jest czytany dwa razy. Raz do porównania, raz do zadania.

W praktyce kompilator może buforować dostęp do zmiennej. Nie wiem o C#, ale w C++ na platformie 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. 

To samo obciążenie raz optymalizacja kodu bajtowego Javy dzieje się chyba currentPrice deklaruje zmienne.

Teoretycznie może się zdarzyć. W praktyce na większości platform nie będzie, ale nie można na to liczyć.

3

Nie jest specjalistą w języku C#, ale nawet var ++ nie jest zapisywaniem wątków, ponieważ może zostać przetłumaczone na podstawie odczytu/zapisu z rejestru w zespole.

Operator trójskładnikowy jest znacznie bardziej skomplikowany. Ma 3 części, podczas gdy każda część może być nieskończenie duża (na przykład wywołanie jakiejś funkcji). Dlatego dość łatwo stwierdzić, że operator trójskładnikowy nie jest bezpieczny dla wątków.

+1

+1; Obawiam się, że x86 nie pozwoli ci "INC" zmienić położenia pamięci, więc zostanie ono przetłumaczone jako przejście do rejestru/inkrementacji/przeniesienia do kombi pamięci. –

1

Jak twierdzą inni, może być buforowany, ale język go nie wymaga.

Możesz użyć Interlocked.CompareExchange, jeśli potrzebujesz blokujących wątków przypisań. Ale biorąc pod uwagę przykład, wybrałabym bardziej zgrubną strategię blokowania.

Powiązane problemy