2011-05-25 15 views
5

Dar el siguiente códigoapropiante un hilo que se está ejecutando sincronizado método

class Test{ 
     double x; 
     public void synchronized a() 
     { 
      x = 0; 
      //do some more stuff 
     } 
     public void b() 
     { 
      x = -1; 
     } 
    } 

Puede el hilo en un(), en el medio de la modificación de x ser substituida por un subproceso que llama b() en el mismo objeto ?

¿El método no sincronizado se ejecuta como una sola operación atómica?

Creo que la otra forma es posible (el hilo en b() puede ser reemplazado por el hilo que llama a() en el mismo objeto ya que b() no está protegido por el bloqueo del objeto de prueba).

¿Puede alguien arrojar algo de luz sobre esto?

Respuesta

11

synchronized para que otros subprocesos no adquieran el mismo monitor. En de ninguna manera hace que la operación sea atómica. En particular:

  • efectos secundarios del método pueden ser observados por otros temas que no están tratando de sincronizar en el mismo monitor
  • Si se produce una excepción, no hay ningún tipo de retroceso
  • otros hilos pueden acceder y modificar los mismos datos utilizados por el método sincronizado, si no están sincronizados en el mismo monitor

b() no está sincronizado, por lo que es completamente posible para un hilo para ser ejecutar a() y otro estar ejecutando b() al mismo tiempo.

+0

Otro problema que no está relacionado con la pregunta de origen es si un método sincronizado necesita demasiado tiempo para ejecutarse, ¿puede el planificador del sistema operativo adelantarse y cambiar a otro hilo? Si es posible, ¿este hilo liberará el bloqueo? – Chao

+0

@Richard: No, eso no liberará el bloqueo. Un método sincronizado puede tomar todo el tiempo que quiera, y ser adelantado varias veces - nada podrá adquirir ese bloqueo mientras lo tenga el método sincronizado. (Tenga en cuenta que al llamar 'wait()' libera el bloqueo y vuelve a adquirirlo más tarde). –

0

Dado que b() no está sincronizado y a() es, es posible que un hilo esté en a() y el otro en b(). Por lo tanto, el valor de x posiblemente se distorsione debido al acceso paralelo no sincronizado a x.

Además, si su código eran como este:

class Test{ 
     double x; 
     public void synchronized a() 
     { 
      x = 0; 
      //do some more stuff 
     } 
     public void b() 
     { 
      x = -1; 
      a(); //added call to a() 
     } 
    } 

y ambos de sus hilos se ejecutan en el misma instancia entonces surge una posibilidad de hilo 1 [actualmente en a() siendo apropiado por Thread 2 [actualmente en b()].

Sin embargo, después de que el subproceso 1 se adelanta, como el subproceso 2 intenta ingresar al método a(), la JVM no lo permitirá; ya que otro hilo [aunque no sea ejecutable] ya tiene el bloqueo. Por lo tanto, ahora se espera que el Subproceso 2 espere hasta que el Subproceso 1 complete la ejecución de a() y lo devuelva. Entonces, el hilo 2 será [probablemente] recuperado y se permitirá la ejecución de a().

Cuestiones relacionadas