34

¿Cuál es la diferencia entre un método sincronizado y un bloque sincronizado en Java?¿Cuál es la diferencia entre un método sincronizado y un bloque sincronizado en Java?

He estado buscando la respuesta en la red, la gente parece estar tan seguro acerca de éste :-(

Mi opinión sería que no hay diferencia entre los dos, a excepción de que el bloque de sincronización podría ser más localizada en su alcance y, por tanto, el bloqueo será de menor tiempo ??

y en caso de bloqueo en un método estático, por lo que se toma el bloqueo? ¿Cuál es el significado de un bloqueo en la clase?

+0

@ try-catch-finally Eso no es un duplicado de esta cuestión; esa pregunta pregunta si un método sincronizado proporciona acceso exclusivo al método solamente, o al objeto completo. –

+0

@MarkRotteveel Tienes razón en términos de los diferentes títulos. Por otro lado, las respuestas de la otra pregunta también cubren las diferencias: determinar la sección sincronizada de algunas afirmaciones (o no) y controlar dónde bloquear (o no tener control sobre eso). –

Respuesta

44

Un método sincronizado utiliza el receptor de método como un bloqueo (es decir this para métodos no estáticos y la clase adjunta para métodos estáticos). Synchronized bloques usa la expresión como un bloqueo.

Así que los dos métodos siguientes son equivalentes se bloqueen prospectivo:

synchronized void mymethod() { ... } 

void mymethod() { 
    synchronized (this) { ... } 
} 

Para los métodos estáticos, la clase será bloqueado:

class MyClass { 
    synchronized static mystatic() { ... } 

    static mystaticeq() { 
    syncrhonized (MyClass.class) { ... } 
    } 
} 

Para bloques sincronizados, se puede utilizar cualquier no null objeto como cerradura:

synchronized (mymap) { 
    mymap.put(..., ...); 
} 

Lock alcance

Para los métodos sincronizados, la cerradura se llevará a cabo en todo el ámbito de método, mientras que en el bloque de synchronized, el bloqueo se lleva a cabo sólo durante ese ámbito de bloque (también conocida como sección crítica). En la práctica, la JVM puede optimizar eliminando algunas operaciones de la ejecución del bloque synchronized si puede demostrar que se puede realizar de forma segura.

+0

Leí hace algún tiempo (perdí la fuente) que el método sincronizado puede ser más fácil de optimizar internamente por JVM que sincronizado en bloque incluso si ese bloque encapsula todo el cuerpo del método. Podría ser un micro-benchmark interesante para probar. –

+1

En el alcance de la cerradura, probablemente quiso decir "... mientras está en el bloque sincronizado, el bloqueo se mantiene solo durante el bloque sincronizado" y no "... mientras que en el método sincronizado, el bloqueo se mantiene solo durante el bloque sincronizado" – mrvincenzo

+2

@Gregory Mostizky Según este artículo, JVM crea menos bytecode para un método sincronizado en comparación con un bloque sincronizado. http://www.ibm.com/developerworks/java/library/j-5things15/index.html?ca=drs- –

3

Sí , esa es una diferencia. La otra es que puede adquirir un candado en otros objetos además de this.

8

Un método sincronizado es la abreviatura. Este:

class Something { 
    public synchronized void doSomething() { 
     ... 
    } 

    public static synchronized void doSomethingStatic() { 
     ... 
    } 
} 

Es decir, para todos los efectos, lo que equivale a esto:

class Something { 
    public void doSomething() { 
     synchronized(this) { 
      ... 
     } 
    } 

    public static void doSomethingStatic() { 
     synchronized(Something.class) { 
      ... 
     } 
    } 
} 

(. Cuando Something.class es el objeto de clase para la clase Something)

Así que de hecho, con una bloque sincronizado, puede ser más específico sobre su bloqueo, y más refinado sobre cuándo quiere usarlo, pero aparte de eso, no hay diferencia.

0

A sincronizados cerraduras método en la instancia de objeto el método está contenida en

Donde como un bloque sincronizado puede bloquear en cualquier objeto -. Típicamente un obect mutex definido como una variable de instancia. Esto permite un mayor control sobre qué cerraduras están en funcionamiento.

2

La diferencia clave es esta: si declara que un método se sincroniza, entonces todo el cuerpo del método se sincroniza; Sin embargo, si usa el bloque sincronizado, puede rodear solo la "sección crítica" del método en el bloque sincronizado, mientras deja el resto del método fuera del bloque.

Si todo el método es parte de la sección crítica, entonces efectivamente no hay diferencia. Si ese no es el caso, entonces debe usar un bloque sincronizado solo alrededor de la sección crítica. Cuantas más afirmaciones tenga en un bloque sincronizado, menos paralelismo general obtendrá, por lo que desea mantenerlas al mínimo.

+0

Seguimiento rápido: ¿Eso significa que un bloqueo sincronizado es menos costoso de usar que un método sincronizado? ? – Everyone

+0

Si el bloque sincronizado incluye todos los contenidos de la función, entonces no hay diferencia. Sin embargo, si usa un bloque sincronizado, puede rodear solo la sección crítica (quizás dejando parte del cálculo fuera de la región sincronizada). Si haces eso, tu programa se ejecutará más rápido. –

0

Mi opinión sería que no hay diferencia entre los dos, excepto que el bloque de sincronización podría estar más localizado en el alcance y por lo tanto, el bloqueo será de menor tiempo ??

Sí. Tienes razón. A diferencia de los métodos synchronized, las sentencias sincronizadas deben especificar el objeto que proporciona el bloqueo intrínseco.

Ejemplo de tutorial java:

public void addName(String name) { 
    synchronized(this) { 
     lastName = name; 
     nameCount++; 
    } 
    nameList.add(name); 
} 

estados sincronizados también son útiles para mejorar la concurrencia con la sincronización de grano fino. Puede encontrar un buen ejemplo en la misma página de tutorial para el caso de uso a continuación.

Supongamos, por ejemplo, que la clase MsLunch tiene dos campos de instancia, c1 y c2, que nunca se utilizan juntos. Todas las actualizaciones de estos campos deben ser synchronized, pero no hay ninguna razón para evitar que una actualización de c1 se interponga con una actualización de c2, y al hacerlo se reduce la concurrencia al crear bloqueos innecesarios. En lugar de utilizar métodos sincronizados o utilizar el bloqueo asociado a esto, creamos dos objetos únicamente para proporcionar bloqueos.

Y en caso de bloqueo en un método estático, ¿en qué se toma la cerradura? ¿Cuál es el significado de un bloqueo en la clase?

En este caso, el hilo adquiere el bloqueo intrínseco para el objeto de Clase asociado a la clase. Por lo tanto, el acceso a los campos estáticos de la clase está controlado por un bloqueo que es distinto del bloqueo para cualquier instancia de la clase.

Al realizar un método como synchronized (no static):

No es posible que dos invocaciones de métodos synchronized sobre el mismo objeto para intercalar. Cuando un hilo está ejecutando un método sincronizado para un objeto, todos los otros hilos que invocan métodos sincronizados para el mismo bloque de objetos (suspenden la ejecución) hasta que el primer hilo termina con el objeto.

Si comete un método que static synchronized:

No es posible que dos invocaciones de métodos static synchronized sobre diferentes objetos de la misma clase para intercalar. Cuando un subproceso ejecuta un método static synchronized para un objeto de Clase A, todos los demás subprocesos que invocan métodos static synchronized en cualquiera de los objetos del bloque Clase A (suspensión de ejecución) hasta que el primer subproceso se completa con la ejecución del método.

a encontrar mejores alternativas a la sincronización en esta pregunta: SE

Avoid synchronized(this) in Java?

Cuestiones relacionadas