2012-10-13 138 views
7

considerar las siguientes dos alternativas de conseguir el número más alto entre currentPrice y 100 ...¿El hilo de operador ternario (? :) está seguro en C#?

int price = currentPrice > 100 ? currentPrice : 100 

int price = Math.Max(currentPrice, 100) 

he planteado esta pregunta porque yo estaba pensando en un contexto donde la variable currentPrice podría ser editado por otros hilos.

En el primer caso ... podría price obtener un valor inferior a 100?

estoy pensando en lo siguiente:

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

Respuesta

8

No se THREADSAFE.

?: se acaba de acceso directo para la normalidad if, por lo que su muestra if es equivalente a una ? - se puede obtener el precio más bajo que el 100 si no hay bloqueo fuera de este código.

+0

respuesta contrario en pocos minutos? : D – dotNETbeginner

+0

@dotNETbeginner :) Buena observación. cuando leí mi primera respuesta, quería darme -10 también. –

3

En teoría, currentPrice se lee dos veces. Una vez para la comparación, una vez para la asignación.

En la práctica, el compilador puede almacenar en caché el acceso a la variable. No sé sobre C#, pero en C++ en 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. 

La carga de una sola mismo sucede en la optimización de código de bytes de Java a menos currentPrice se declara volátil.

Por lo tanto, en teoría, puede suceder. En la práctica, en la mayoría de las plataformas, no lo hará, pero no puede contar con eso.

3

No es un especialista en C#, pero incluso var ++ no se enrosque ahorrar, ya que pueden traducirse a partir de la lectura en/escritura del registro en el montaje.

operador ternario es mucho más complicado. Tiene 3 partes, mientras que cada parte puede ser infinitamente grande (por ejemplo, llamar a alguna función). Por lo tanto, es bastante fácil concluir que el operador ternario no es seguro para subprocesos.

+1

+1; Estoy x86 miedo no te deja 'INC'rement una posición de memoria, por lo que _deberá_ ser traducido como una medida para registro/incremento/movimiento para combo memoria. –

1

Como otros han dicho, que podría ser en caché, pero el idioma no lo requiere.

Puede utilizar Interlocked.CompareExchange si necesita bloquear las asignaciones de libre hebras. Pero dado el ejemplo, elegiría una estrategia de bloqueo de grano más grueso.

Cuestiones relacionadas