2012-06-25 13 views
10

Tengo una duda con respecto a la Sincronización de Java. Quiero saber si tengo tres métodos sincronizados en mi clase y un hilo adquiere el bloqueo en un método sincronizado; los otros dos serán bloqueados. Estoy haciendo esta pregunta porque estoy confundido con la siguiente declaración.¿Cómo funciona la sincronización en Java?

Mientras que un hilo está dentro de un método sincronizado de un objeto, todos los otros hilos que desean ejecutar este método sincronizado o cualquier otro método sincronizado del objeto tendrán que esperar. Esta restricción no se aplica al hilo que ya tiene el bloqueo y está ejecutando un método sincronizado del objeto. Tal método puede invocar otros métodos sincronizados del objeto sin ser bloqueado. Los métodos no sincronizados del objeto pueden, por supuesto, llamarse en cualquier momento por cualquier hilo

+1

¿Cuál es la fuente de esa afirmación y cuál es su confusión? Parece que lo entiendes. Tenga cuidado con el punto muerto cuando acceda a un método sincronizado desde otro. – Sridhar

+0

Re: "... otros dos estarán bloqueados". No se impedirá que el subproceso que se ejecuta actualmente que ya tiene el bloqueo invoque otro método sincronizado en el mismo objeto, sin embargo, cualquier otro subproceso se bloqueará (es decir, se obligará a esperar hasta que se les otorgue el bloqueo). Max tiene una buena respuesta que habla sobre si está bloqueando el objeto en sí mismo (es decir, esto) u otra variable de objeto por completo. – Brad

Respuesta

7

La sincronización en java se realiza mediante la búsqueda del monitor en algún Objeto específico. Por lo tanto, si usted hace esto:

class TestClass { 
    SomeClass someVariable; 

    public void myMethod() { 
     synchronized (someVariable) { 
      ... 
     } 
    } 

    public void myOtherMethod() { 
     synchronized (someVariable) { 
      ... 
     } 
    } 
} 

Entonces esos dos bloques serán protegidos por la ejecución de 2 hilos diferentes en cualquier momento mientras someVariable no se modifica. Básicamente, se dice que esos dos bloques están sincronizados con la variable someVariable.

Cuando pone synchronized en el método, básicamente significa lo mismo que synchronized (this), es decir, una sincronización en el objeto en el que se ejecuta este método.

Es decir:

public synchronized void myMethod() { 
    ... 
} 

significa lo mismo que:

public void myMethod() { 
    synchronized (this) { 
     ... 
    } 
} 

lo tanto, para responder a su pregunta - sí, las discusiones no serán capaces de llamar a esos métodos al mismo tiempo en diferentes hilos, ya que ambos tienen una referencia al mismo monitor, el monitor del objeto this.

+0

Máx., El término "bloqueo" en su última oración es engañoso. Creo que quisiste decir "... ya que ambos tienen una referencia al mismo monitor". Dos hilos no pueden mantener un bloqueo desde el mismo monitor al mismo tiempo. – Brad

+0

@Brad Gracias por la corrección, actualizada. – bezmax

+0

Si no recibe lo que ha transmitido en el primer párrafo, ¿puede explicarlo con términos más simples? – userab

1

Sí.
Para ejecutar el método sincronizado, el hilo necesita obtener el bloqueo del objeto y solo un hilo a la vez puede obtener el bloqueo del objeto.

0

Cada objeto java (instancia de clase) tiene un objeto mutex. La palabra clave sincronizada en frente de un método significa que el hilo en ejecución tiene que obtener el bloqueo en el mutex para ese objeto. De hecho,

public synchronized doSomething(){ 
    ... 
} 

es exactamente lo mismo que esto:

public doSomething(){ 
    synchronized(this){ 
     ... 
    } 
} 

Así que sí, sólo habrá un hilo de ejecución de un método sincronizado por instancia de la clase.

Tenga en cuenta que a veces esto puede ser poco óptimo, ya que desea proteger las modificaciones, pero están bien con lecturas concurrentes, en cuyo caso, en lugar de la palabra clave sincronizada, es posible que desee consultar ReadWriteLock.

-1

No estoy seguro de qué es lo que le resulta confuso, pero al adquirir un bloqueo impide que otros hilos lo adquieran mientras lo mantiene, y todos los métodos sincronizados no estáticos de una clase se sincronizan en el mismo objeto, por lo que la respuesta a su pregunta es 'sí', suponiendo que lo haya entendido correctamente. No sé qué más podría significar 'sincronizado', o qué utilidad tendría con otro significado.

0

bueno, solo hay un bloqueo por objeto. y todos los métodos sincronizados están bloqueados por este bloqueo. Entonces, cualquiera que sea el hilo que adquiera el bloqueo a la vez, está autorizado para pasar por todos los métodos sincronizados. Pero los hilos que esperan el bloqueo no pueden entrar en métodos de sincronización hasta que obtengan el bloqueo.

Por lo tanto, a la vez, solo las reglas de subprocesos y otras tienen que esperar para ingresar cualquier método sincronizado, no importa si el hilo conductor está ejecutando ese método o no.

0

Sí, todos los hilos, excepto el que adquirió el bloqueo, tendrán que esperar hasta que se desbloquee nuevamente para poder ejecutar uno de los tres métodos sincronizados.

Recuerde, un método sincronizado es lo mismo que un método normal rodeado por

synchronized(this) { 
    // method body 
} 
0

Es cierto y lo hace de esta manera. Es necesario también para la coherencia de los datos de ese objeto.

Supongamos que esta validación no está allí y hay una variable x que está siendo manipulada por 2 métodos diferentes xxx() y yyy().

si el subproceso A obtiene el bloqueo del método xxx() que está manipulando x = 5 y el segundo subproceso B obtiene el bloqueo del método yyy() y manipula x = -5 entonces al final del método xxx() esperando x = 5 pero obtendrá x = 0 que es incorrecto.

Por eso se implementa de esta manera.

0

Si una clase tiene 4 métodos de sincronización, entonces sí a la vez solo un hilo tendrá acceso a esos métodos. Supongo que la duda es que cada subproceso puede acceder a los métodos sincronizados de diff a la vez para la instancia de una sola clase. La respuesta es no. Solo un hilo puede acceder a métodos sincronizados a la vez.

Cuestiones relacionadas