2012-10-13 8 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.