2011-03-16 5 views
5

me di cuenta el siguiente código de nuestros programadores extranjeros:dentro de una cerradura

private Client[] clients = new Client[0]; 

public CreateClients(int count) 
{ 
    lock (clients) 
    { 
     clients = new Client[count]; 

     for(int i=0; i<count; i++) 
     { 
      Client[i] = new Client();//Stripped 
     } 
    } 
} 

No es adecuado código exactamente pero me preguntaba qué es exactamente esto va a hacer. ¿Esto se bloqueará en un nuevo objeto cada vez que se llame a este método?

+5

Es una mala práctica "bloquear" matrices. Mejor definir el objeto adicional para la sincronización – Stecya

+1

El código tal como está escrito es incorrecto, ¿no? Dentro de la cerradura no deberían ser clientes = nuevo Cliente [conteo], y luego clientes [i] = nuevo Cliente() ;? – rsbarro

+0

Tienes razón, lo editó. – Carra

Respuesta

5

Para responder a su pregunta de "¿Me preguntaba qué es exactamente esto va a hacer" considere lo que sucede si dos hilos trata de hacer esto

Thread 1: locks on the clients reference, which is `new Client[0]` 
    Thread 1 has entered the critical block 
Thread 1: makes a array and assigns it to the clients reference 
Thread 2: locks on the clients reference, which is the array just made in thread 1 
    Thread 2 has entered the critical block 

Sabe que tiene dos hilos en el bloque crítico al mismo tiempo. Eso es malo.

+0

Por lo tanto, cada vez que un hilo entra probablemente se bloqueará en un objeto nuevo. Gracias por la explicación. – Carra

1

Este código es incorrecto: se bloqueará en una nueva instancia cada vez que se llame.

Debe quedar como que:

private static readonly object clientsLock = new object(); 
private static string[] Clients = null; 

public CreateClients(int count) 
{ 
    if(clients == null) 
    { 
     lock (clientsLock) 
     { 
      if(clients == null) 
      { 
       clients = new string[count]; 

       for(int i=0; i<count; i++) 
       { 
        client[i] = new Client();//Stripped 
       } 
      } 
     } 
    } 
} 

No hay ningún punto en el bloqueo cada vez que el método se llama - es por eso que rodea el caso de la cláusula.

+5

Esto nunca entrará, porque nunca obtendrás tus primeros bloques de 'if clients! = Null' Siempre será nulo porque la única forma de eliminar su nulidad es dentro del bloque'! = Null' – corsiKa

+0

Gracias Glowcoder - error tonto, lo siento. –

+0

Sí, probablemente debería ser "if (clients == null)" dos veces. – Polyfun

1

Uso:
private object = new Object();

lock(object){ 

//your code 

} 
+4

Dado que es un método de instancia, no veo ninguna razón para usar un objeto de bloqueo estático. –

+0

Sé que el código es incorrecto, me preguntaba qué hace :) – Carra

0

creo que tiene usted razón para dudar de este código!

Este código se bloqueará en la instancia anterior cada vez; este podría ser el efecto deseado, pero lo dudo. No evitará que múltiples hilos creen múltiples matrices.

1

Este lock realmente no hace nada. Bloquea una instancia de un objeto que se cambia inmediatamente para que otros hilos que ingresen a este método sean lock en un objeto diferente. El resultado es 2 hilos que se ejecutan en el medio del lock, que probablemente no es lo que se pretendía.

Un enfoque mucho mejor es usar un objeto que no cambian diferente para bloquear el

private readonly object clientsLock = new object(); 
private Client[] clients = new Client[0]; 

public CreateClients(int count) {  
    lock (clientsLock) {   
    clients = new string[count]; 
    ... 
    } 
} 
Cuestiones relacionadas