2012-06-21 6 views
5

¿Qué sucede en el siguiente código? Funciona la sincronización? Esta es una pregunta de entrevista.¿Qué sucede si la variable de sincronización se reasigna en java?

class T 
{ 
    public static void main(String args[]) 
    { 
     Object myObject = new Object(); 
     synchronized (myObject) 
     { 
      myObject = new Object(); 
     } // end sync 
    } 
} 
+4

Si su bloque sincronizado está en el circuito principal y no en un circuito, solo se ejecutará una vez. No tiene sentido sincronizar aquí (a menos que llame a ese principal desde otro principal, lo que sería extraño). – assylias

Respuesta

4

Cada vez que ingresa al bloque sincronizado, se sincroniza en un objeto diferente. La mayoría de las veces esto no hará más que confundirlo, pero hay una pequeña posibilidad de que dos hilos vean el mismo objeto y esperen.

Por esta razón, cualquier analizador de código le dará una advertencia si se está sincronizando en un campo que no es final.

1

Todavía libera el mismo monitor que fue adquirida, pero cualquier otro código que también bloquea el uso de myObject (imposible aquí ya que es una variable local, por lo que la sincronización fundamentalmente sin sentido) podría comenzar a utilizar el nuevo objeto.

No olvide que la sincronización se aplica a objetos (o más bien, los monitores asociados a objetos) - no variables. El monitor que se adquiere/libera solo depende del valor de la expresión cuando se inicia del bloque sincronizado. La expresión es no reevaluada al final del bloque sincronizado.

0

No, no funciona. Cada vez que aparece un nuevo hilo, se crea un nuevo myObject. ¡Particularmente ahora que myObject es una variable local!

No funcionaría aunque myObject sea un miembro de la clase ya que cambiaría el objeto que está bloqueando. Vea la pregunta sobre synchronization of non-final field para una explicación más larga.

0

No veo la razón detrás de este código ya que el objeto no está compartido por ningún subproceso. La eliminación del bloque sincronizado no tendrá ningún efecto en el resultado real en ningún caso. Simplemente hará que su código se ejecute más rápido

0

Primero necesita obtener el bloqueo de myObject, si este bloqueo fue bloqueado, debe esperar hasta que se libere el bloqueo.

La sincronización requiere un entorno multihilo. Pero parece que su código no tiene nada que ver con la concurrencia. Por lo tanto, siento decirle que NO HABRÁ nada.

0

Ejecute el código y analice el resultado.

public class Test { 
    static Foo o = new Foo(0); 
    static class Foo { 
     private int i = 0; 
     Foo(int i) { 
      this.i = i; 
     } 
     public void addOnce() { 
      this.i++; 
     } 
     public String toString() { 
      return String.valueOf(i); 
     } 
    } 
    public static void main(String args[]) { 
     test1(); 
     try {Thread.sleep(10000);} catch (Exception e) {} 
     test2(); 
    } 
    public static void test1() { 
     Runnable r = new Runnable() { 
      public void run() { 
       synchronized (o) { 
        System.out.println("1------>"+o); 
        o = new Foo(1); 
        try {Thread.sleep(3000);} catch (Exception e) {} 
        System.out.println("1------>"+o); 
       } 
      } 
     }; 
     new Thread(r).start(); 
     new Thread(r).start(); 
    } 
    public static void test2() { 
     Runnable r = new Runnable() { 
      public void run() { 
       synchronized (o) { 
        System.out.println("2------>"+o); 
        o.addOnce(); 
        try {Thread.sleep(3000);} catch (Exception e) {} 
        System.out.println("2------>"+o); 
       } 
      } 
     }; 
     new Thread(r).start(); 
     new Thread(r).start(); 
    } 
} 
Cuestiones relacionadas