¿Qué significa 'sincronizado'?

994

Tengo algunas preguntas sobre el uso y la importancia de la synchronizedpalabra clave.

  • ¿Cuál es el significado de la synchronizedpalabra clave?
  • ¿Cuándo deberían ser los métodos synchronized?
  • ¿Qué significa programática y lógicamente?
Johanna
fuente
1
discusión útil entre hashmap y hashtable, y sincronización: stackoverflow.com/questions/40471/java-hashmap-vs-hashtable
limc
2
Posible duplicado de Cómo funciona el sincronizado en Java
Marian Paździoch
1
Revisé todo el enlace de documentación desde el primer comentario, y no entendí hasta que llegué al último párrafo. En lugar de pegar enlaces y no citar nada, puede pegar enlaces y agregar una cita es más útil.
Rakib

Respuestas:

878

La synchronizedpalabra clave trata sobre diferentes hilos que leen y escriben en las mismas variables, objetos y recursos. Este no es un tema trivial en Java, pero aquí hay una cita de Sun:

synchronized Los métodos permiten una estrategia simple para prevenir la interferencia del hilo y los errores de consistencia de la memoria: si un objeto es visible para más de un hilo, todas las lecturas o escrituras en las variables de ese objeto se realizan a través de métodos sincronizados.

En pocas palabras: cuando tienes dos hilos que leen y escriben en el mismo 'recurso', digamos una variable llamada foo, debes asegurarte de que estos hilos accedan a la variable de forma atómica. Sin la synchronizedpalabra clave, es posible que su hilo 1 no vea el cambio hecho en el hilo 2 fooo, lo que es peor, solo se puede cambiar a medias. Esto no sería lo que lógicamente espera.

Nuevamente, este es un tema no trivial en Java. Para obtener más información, explore los temas aquí sobre SO y las Interwebs sobre:

Siga explorando estos temas hasta que el nombre "Brian Goetz" se asocie permanentemente con el término "concurrencia" en su cerebro.

Stu Thompson
fuente
71
Entonces, ¿básicamente esta palabra clave sincronizada hace que sus métodos sean seguros para subprocesos?
Rigo Vides el
82
La palabra clave sincronizada es una de las herramientas que hacen que su hilo de código sea seguro. Solo usar sincronizado en un método o variable en sí mismo puede o no hacer el truco. Tener una comprensión básica del modelo de memoria Java es realmente importante para obtener la concurrencia correcta.
Stu Thompson
28
A menos que sea Brian Goetz (o tal vez Jon Skeet), es casi imposible corregir la concurrencia de Java solo con las primitivas del lenguaje (sincronizadas, volátiles). Para empezar, utiliza el paquete java.util.concurrent y construye sobre eso.
Thilo el
12
Más claramente: los métodos sincronizados no se pueden invocar al mismo tiempo desde varios subprocesos.
peterh - Restablecer Monica
2
@peterh sincronizado hace más que eso, de ahí la explicación más detallada
Stu Thompson
294

Bueno, creo que ya tuvimos suficientes explicaciones teóricas, así que considera este código

public class SOP {
    public static void print(String s) {
        System.out.println(s+"\n");
    }
}

public class TestThread extends Thread {
    String name;
    TheDemo theDemo;
    public TestThread(String name,TheDemo theDemo) {
        this.theDemo = theDemo;
        this.name = name;
        start();
    }
    @Override
    public void run() {
        theDemo.test(name);
    }
}

public class TheDemo {
    public synchronized void test(String name) {
        for(int i=0;i<10;i++) {
            SOP.print(name + " :: "+i);
            try{
                Thread.sleep(500);
            } catch (Exception e) {
                SOP.print(e.getMessage());
            }
        }
    }
    public static void main(String[] args) {
        TheDemo theDemo = new TheDemo();
        new TestThread("THREAD 1",theDemo);
        new TestThread("THREAD 2",theDemo);
        new TestThread("THREAD 3",theDemo);
    }
}

Nota: synchronizedbloquea la llamada del siguiente subproceso al método test () siempre que la ejecución del subproceso anterior no haya finalizado. Los hilos pueden acceder a este método uno a la vez. Sin synchronizedtodos los hilos pueden acceder a este método simultáneamente.

Cuando un hilo llama al método sincronizado 'prueba' del objeto (aquí el objeto es una instancia de la clase 'TheDemo') adquiere el bloqueo de ese objeto, cualquier hilo nuevo no puede llamar a NINGÚN método sincronizado del mismo objeto siempre que el hilo anterior que había adquirido el bloqueo no libera el bloqueo.

Algo similar ocurre cuando se llama a cualquier método estático sincronizado de la clase. El subproceso adquiere el bloqueo asociado con la clase (en este caso, cualquier subproceso sincronizado no estático de una instancia de esa clase puede ser llamado por cualquier subproceso porque ese bloqueo de nivel de objeto todavía está disponible). Cualquier otro subproceso no podrá llamar a ningún método estático sincronizado de la clase, siempre que el subproceso de nivel de clase no se libere por el subproceso que actualmente mantiene el bloqueo.

Salida con sincronizado

THREAD 1 :: 0
THREAD 1 :: 1
THREAD 1 :: 2
THREAD 1 :: 3
THREAD 1 :: 4
THREAD 1 :: 5
THREAD 1 :: 6
THREAD 1 :: 7
THREAD 1 :: 8
THREAD 1 :: 9
THREAD 3 :: 0
THREAD 3 :: 1
THREAD 3 :: 2
THREAD 3 :: 3
THREAD 3 :: 4
THREAD 3 :: 5
THREAD 3 :: 6
THREAD 3 :: 7
THREAD 3 :: 8
THREAD 3 :: 9
THREAD 2 :: 0
THREAD 2 :: 1
THREAD 2 :: 2
THREAD 2 :: 3
THREAD 2 :: 4
THREAD 2 :: 5
THREAD 2 :: 6
THREAD 2 :: 7
THREAD 2 :: 8
THREAD 2 :: 9

Salida sin sincronizado

THREAD 1 :: 0
THREAD 2 :: 0
THREAD 3 :: 0
THREAD 1 :: 1
THREAD 2 :: 1
THREAD 3 :: 1
THREAD 1 :: 2
THREAD 2 :: 2
THREAD 3 :: 2
THREAD 1 :: 3
THREAD 2 :: 3
THREAD 3 :: 3
THREAD 1 :: 4
THREAD 2 :: 4
THREAD 3 :: 4
THREAD 1 :: 5
THREAD 2 :: 5
THREAD 3 :: 5
THREAD 1 :: 6
THREAD 2 :: 6
THREAD 3 :: 6
THREAD 1 :: 7
THREAD 2 :: 7
THREAD 3 :: 7
THREAD 1 :: 8
THREAD 2 :: 8
THREAD 3 :: 8
THREAD 1 :: 9
THREAD 2 :: 9
THREAD 3 :: 9
Dheeraj Sachan
fuente
77
Gran ejemplo, es bueno conocer la teoría, pero el código siempre es más específico y completo.
Santi Iglesias
2
@SantiIglesias "Completo"? No Este ejemplo demuestra el comportamiento de bloqueo de synchronized, pero se ignora la coherencia de la memoria.
Stu Thompson
2
La consistencia de la memoria de @Stu Thompson es el resultado del bloqueo
Dheeraj Sachan
@DheerajSachan Según esa lógica, el uso de un ReentrantLock daría como resultado consistencia de memoria. No lo hace.
Stu Thompson
3
@boltup_im_coding: El método start () pone el Thread en un estado "RUNNABLE", lo que significa que está listo para ejecutarse o ya se está ejecutando. Puede suceder que otro subproceso (generalmente pero no necesariamente con mayor prioridad) en estado Runnable salte a la cola y comience a ejecutarse. En el ejemplo anterior, THREAD 3 obtuvo CPU antes de THREAD 2.
Sahil J
116

La synchronizedpalabra clave evita el acceso concurrente a un bloque de código u objeto por múltiples hilos. Todos los métodos de Hashtableson synchronized, por lo que solo un subproceso puede ejecutar cualquiera de ellos a la vez.

Cuando utilice no synchronizedconstrucciones como HashMap, debe crear características de seguridad de subprocesos en su código para evitar errores de coherencia.

jmort253
fuente
81

synchronizedsignifica que en un entorno de subprocesos múltiples, un objeto que tiene synchronizedmétodo (s) / bloque (s) no permite que dos subprocesos accedan al synchronizedmétodo (s) / bloque (es) de código al mismo tiempo. Esto significa que un hilo no puede leer mientras otro hilo lo actualiza.

El segundo hilo esperará hasta que el primer hilo complete su ejecución. La sobrecarga es la velocidad, pero la ventaja es la consistencia garantizada de los datos.

Sin embargo, si su aplicación es de un solo subproceso, los synchronizedbloques no proporcionan beneficios.

Codemwnci
fuente
54

La synchronizedpalabra clave hace que un subproceso obtenga un bloqueo al ingresar el método, por lo que solo un subproceso puede ejecutar el método al mismo tiempo (para la instancia de objeto dada, a menos que sea un método estático).

Esto se llama con frecuencia hacer que la clase sea segura para subprocesos, pero yo diría que esto es un eufemismo. Si bien es cierto que la sincronización protege el estado interno del Vector para que no se corrompa, esto generalmente no ayuda mucho al usuario de Vector.

Considera esto:

 if (vector.isEmpty()){
     vector.add(data);
 }

A pesar de que los métodos involucrados están sincronizados, debido a que se están bloqueando y desbloqueando individualmente, dos hilos desafortunadamente pueden crear un vector con dos elementos.

En efecto, también debe sincronizar el código de su aplicación.

Debido a que la sincronización a nivel de método es a) costosa cuando no la necesita yb) insuficiente cuando necesita sincronización, ahora hay reemplazos no sincronizados (ArrayList en el caso de Vector).

Más recientemente, se lanzó el paquete de simultaneidad, con una serie de utilidades inteligentes que se ocupan de problemas de subprocesos múltiples.

Thilo
fuente
27

Visión general

La palabra clave sincronizada en Java tiene que ver con la seguridad de subprocesos, es decir, cuando varios subprocesos leen o escriben la misma variable.
Esto puede suceder directamente (accediendo a la misma variable) o indirectamente (usando una clase que usa otra clase que accede a la misma variable).

La palabra clave sincronizada se usa para definir un bloque de código donde múltiples hilos pueden acceder a la misma variable de manera segura.

Más adentro

En cuanto a la sintaxis, la synchronizedpalabra clave toma un Objectparámetro como es (llamado un objeto de bloqueo ), que luego es seguido por un { block of code }.

  • Cuando la ejecución encuentra esta palabra clave, el hilo actual intenta "bloquear / adquirir / poseer" (elija) el objeto de bloqueo y ejecutar el bloque de código asociado después de que se haya adquirido el bloqueo.

  • Se garantiza que cualquier escritura en variables dentro del bloque de código sincronizado será visible para cualquier otro subproceso que ejecute de manera similar el código dentro de un bloque de código sincronizado utilizando el mismo objeto de bloqueo .

  • Solo un subproceso a la vez puede retener el bloqueo, durante el cual todos los demás subprocesos que intentan adquirir el mismo objeto de bloqueo esperarán (pausarán su ejecución). El bloqueo se liberará cuando la ejecución salga del bloque de código sincronizado.

Métodos sincronizados:

Adición de synchronizedpalabra clave para una definición de método es igual a todo el cuerpo del método de ser envuelto en un bloque de código sincronizado con el objeto de bloqueo ser this (para los métodos de instancia) y ClassInQuestion.getClass() (para los métodos de clase) .

- El método de instancia es un método que no tiene staticpalabra clave.
- El método de clase es un método que tienestatic palabra clave.

Técnico

Sin sincronización, no se garantiza en qué orden ocurren las lecturas y escrituras, posiblemente dejando la variable con basura.
(Por ejemplo, una variable podría terminar con la mitad de los bits escritos por un hilo y la mitad de los bits escritos por otro hilo, dejando la variable en un estado que ninguno de los hilos intentó escribir, sino un desorden combinado de ambos).

No es suficiente completar una operación de escritura en un hilo antes (tiempo de reloj de pared) de que otro hilo lo lea, porque el hardware podría haber almacenado en caché el valor de la variable, y el hilo de lectura vería el valor almacenado en caché en lugar de lo que se escribió eso.

Conclusión

Por lo tanto, en el caso de Java, debe seguir el Modelo de memoria de Java para asegurarse de que no se produzcan errores de subprocesamiento.
En otras palabras: use sincronización, operaciones atómicas o clases que los usen para usted bajo los capó.

Fuentes

http://docs.oracle.com/javase/specs/jls/se8/html/index.html
Java® Language Specification, 2015-02-13

Gima
fuente
Lo siento, pero tengo este ejemplo y no entiendo el significado: `Integer i1 = Arrays.asList (1,2,3,4,5) .stream (). FindAny (). Get (); sincronizado (i1) {Integer i2 = Arrays.asList (6,7,8,9,10) .parallelStream () .sorted () .findAny (). get (); System.out.println (i1 + "" + i2); } `1. ¿Por qué invocaste el bloque en primera instancia y esta invocación no tiene efecto en el código? 2. La segunda instancia será segura para subprocesos, a pesar de la invocación del bloque en la primera?
Adryr83
1
@ Adryr83 Si tiene una pregunta, probablemente podría hacerla publicando una nueva pregunta. Pero como estamos aquí, analizaré lo que pueda (su pregunta es un poco difícil de entender). Por lo que puedo decir sobre ese fragmento de código, no parece contener nada que requiera sincronización. Está fuera de contexto. Sugerencia: si puede, intente dividir el código en partes individuales más pequeñas y luego busque respuestas sobre ellas. Es mucho más fácil tratar de comprender problemas pequeños y aislados, que tratar de descubrir un gran bloque de código.
Gima
21

Piense en ello como una especie de torniquete como el que podría encontrar en un campo de fútbol. Hay vapores paralelos de personas que desean entrar pero en el torniquete están 'sincronizados'. Solo una persona a la vez puede pasar. Todos aquellos que quieran pasar lo harán, pero pueden tener que esperar hasta que puedan pasar.

Pablo
fuente
16

¿Cuál es la palabra clave sincronizada?

Los hilos se comunican principalmente compartiendo el acceso a los campos y los campos de referencia de los objetos a los que se refieren. Esta forma de comunicación es extremadamente eficiente, pero hace posibles dos tipos de errores: interferencia de hilo y errores de consistencia de memoria . La herramienta necesaria para evitar estos errores es la sincronización.

Los bloques o métodos sincronizados evitan la interferencia del hilo y aseguran que los datos sean consistentes. En cualquier momento, solo un subproceso puede acceder a un bloque o método sincronizado ( sección crítica ) mediante la adquisición de un bloqueo. Otros hilos esperarán a que se libere el bloqueo para acceder a la sección crítica .

¿Cuándo se sincronizan los métodos?

Los métodos se sincronizan cuando agrega synchronizeda la definición o declaración del método. También puede sincronizar un bloque de código particular con un método.

¿Qué significa programáticamente y lógicamente?

Significa que solo un hilo puede acceder a la sección crítica mediante la adquisición de un bloqueo. A menos que este hilo libere este bloqueo, todos los otros hilos tendrán que esperar para adquirir un bloqueo. No tienen acceso para ingresar a la sección crítica sin adquirir el bloqueo.

Esto no se puede hacer con una magia. Es responsabilidad del programador identificar las secciones críticas en la aplicación y protegerlas en consecuencia. Java proporciona un marco para proteger su aplicación, pero dónde y qué deben protegerse todas las secciones es responsabilidad del programador.

Más detalles en la página de documentación de Java

Cerraduras intrínsecas y sincronización:

La sincronización se basa en una entidad interna conocida como bloqueo intrínseco o bloqueo de monitor. Los bloqueos intrínsecos desempeñan un papel en ambos aspectos de la sincronización: imponen el acceso exclusivo al estado de un objeto y establecen relaciones antes de que sean esenciales para la visibilidad.

Cada objeto tiene un bloqueo intrínseco asociado . Por convención, un hilo que necesita acceso exclusivo y consistente a los campos de un objeto tiene que adquirir el bloqueo intrínseco del objeto antes de acceder a ellos, y luego liberar el bloqueo intrínseco cuando se hace con ellos.

Se dice que un subproceso posee el bloqueo intrínseco entre el momento en que adquirió el bloqueo y lo liberó. Mientras un hilo posea un bloqueo intrínseco, ningún otro hilo puede adquirir el mismo bloqueo. El otro hilo se bloqueará cuando intente adquirir el bloqueo.

Cuando un hilo libera un bloqueo intrínseco, se establece una relación antes de que ocurra entre esa acción y cualquier adquisición posterior del mismo bloqueo.

Hacer métodos sincronizados tiene dos efectos :

Primero, no es posible intercalar dos invocaciones de métodos sincronizados en el mismo objeto.

Cuando un subproceso está ejecutando un método sincronizado para un objeto, todos los demás subprocesos que invocan métodos sincronizados para el mismo bloque de objeto (suspender la ejecución) hasta que el primer subproceso se realiza con el objeto.

En segundo lugar, cuando sale un método sincronizado, establece automáticamente una relación de suceso anterior con cualquier invocación posterior de un método sincronizado para el mismo objeto.

Esto garantiza que los cambios en el estado del objeto sean visibles para todos los hilos.

Busque otras alternativas a la sincronización en:

¿Evitar sincronizado (esto) en Java?

Ravindra babu
fuente
11

Synchronized normal methodequivalente a Synchronized statement(use esto)

class A {
    public synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(this) {
             // all function code
        }
    } 
}

Synchronized static methodequivalente a Synchronized statement(usar clase)

class A {
    public static synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(A.class) {
             // all function code
        }
    } 
}

Sentencia sincronizada (usando variable)

class A {
    private Object lock1 = new Object();

    public void methodA() {
        synchronized(lock1 ) {
             // all function code
        }
    } 
}

Para synchronized, tenemos ambos Synchronized Methodsy Synchronized Statements. Sin embargo, Synchronized Methodses similar a Synchronized Statementslo que necesitamos entender Synchronized Statements.

=> Básicamente, tendremos

synchronized(object or class) { // object/class use to provides the intrinsic lock
   // code 
}

Aquí hay 2 pensamientos que ayudan a entender synchronized

  • Cada objeto / clase tiene un intrinsic lockasociado con él.
  • Cuando un hilo invoca a synchronized statement, automáticamente adquiere el intrinsic lockpara ese synchronized statement'sobjeto y lo libera cuando el método regresa. Mientras un hilo posea un intrinsic lock, NINGÚN otro hilo puede adquirir el MISMO bloqueo => hilo seguro.

=> Cuando se thread Ainvoca synchronized(this){// code 1}=> todo el código de bloqueo (dentro de la clase) donde have synchronized(this)y all synchronized normal method(dentro de la clase) está bloqueado porque el MISMO bloqueo. Se ejecutará después del thread Adesbloqueo ("// código 1" terminado).

Este comportamiento es similar a synchronized(a variable){// code 1}o synchronized(class).

MISMO BLOQUEO => bloqueo (¿no depende de qué método o qué afirmaciones?)

¿Usar método sincronizado o declaraciones sincronizadas?

Prefiero synchronized statementsporque es más extensible. Ejemplo, en el futuro, solo necesita sincronizar una parte del método. Por ejemplo, tiene 2 métodos sincronizados y no tiene ninguna relevancia entre sí, sin embargo, cuando un subproceso ejecuta un método, bloqueará el otro método (puede evitarlo mediante el uso synchronized(a variable)).

Sin embargo, aplicar el método sincronizado es simple y el código parece simple. Para alguna clase, solo hay 1 método sincronizado, o todos los métodos sincronizados en la clase son relevantes entre sí => podemos usar synchronized methodpara hacer el código más corto y fácil de entender

Nota

(no es relevante para mucho synchronized, es la diferencia entre objeto y clase o no estático y estático).

  • Cuando usa synchronizedun método normal synchronized(this)o synchronized(non-static variable)se sincronizará la base en cada instancia de objeto.
  • Cuando use un synchronizedmétodo estático synchronized(class)o synchronized(static variable)se sincronizará en base a la clase

Referencia

https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

Espero que ayude

Phan Van Linh
fuente
11

Aquí hay una explicación de The Java Tutorials .

Considere el siguiente código:

public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }
}

si countes una instancia de SynchronizedCounter, sincronizar estos métodos tiene dos efectos:

  • Primero, no es posible intercalar dos invocaciones de métodos sincronizados en el mismo objeto. Cuando un subproceso está ejecutando un método sincronizado para un objeto, todos los demás subprocesos que invocan métodos sincronizados para el mismo bloque de objeto (suspender la ejecución) hasta que el primer subproceso se realiza con el objeto.
  • En segundo lugar, cuando sale un método sincronizado, establece automáticamente una relación de suceso anterior con cualquier invocación posterior de un método sincronizado para el mismo objeto. Esto garantiza que los cambios en el estado del objeto sean visibles para todos los hilos.
Shahryar Saljoughi
fuente
9

A mi entender, sincronizado básicamente significa que el compilador escribe un monitor.enter y monitor.exit alrededor de su método. Como tal, puede ser seguro para subprocesos dependiendo de cómo se use (lo que quiero decir es que puede escribir un objeto con métodos sincronizados que no sean seguros para subprocesos dependiendo de lo que haga su clase).

Spence
fuente
5

Lo que faltan las otras respuestas es un aspecto importante: las barreras de memoria . La sincronización de subprocesos consiste básicamente en dos partes: serialización y visibilidad. Aconsejo a todos que busquen en Google "barrera de memoria jvm", ya que es un tema no trivial y extremadamente importante (si modifica los datos compartidos a los que acceden varios subprocesos). Una vez hecho esto, le aconsejo que mire las clases del paquete java.util.concurrent que ayudan a evitar el uso de la sincronización explícita, lo que a su vez ayuda a mantener los programas simples y eficientes, tal vez incluso evitando puntos muertos.

Un ejemplo de ello es ConcurrentLinkedDeque . Junto con el patrón de comando , permite crear subprocesos de trabajo altamente eficientes al rellenar los comandos en la cola concurrente: no se necesita sincronización explícita, no hay puntos muertos posibles, no es necesario dormir (), solo sondea la cola llamando a take ().

En resumen: la "sincronización de memoria" ocurre implícitamente cuando inicia un subproceso, un subproceso finaliza, lee una variable volátil, desbloquea un monitor (deja un bloque / función sincronizado), etc. Esta "sincronización" afecta (en cierto sentido, "se sonroja"). ") todas las escrituras hechas antes de esa acción en particular. En el caso del mencionado ConcurrentLinkedDeque , la documentación "dice":

Efectos de coherencia de la memoria: al igual que con otras colecciones concurrentes, las acciones en un subproceso antes de colocar un objeto en un ConcurrentLinkedDeque ocurren antes de las acciones posteriores al acceso o eliminación de ese elemento del ConcurrentLinkedDeque en otro subproceso.

Este comportamiento implícito es un aspecto un tanto pernicioso porque la mayoría de los programadores de Java sin mucha experiencia solo tomarán mucho por lo debido. Y de repente tropezar con este hilo después de que Java no está haciendo lo que se supone que debe hacer en la producción donde hay una carga de trabajo diferente, y es bastante difícil probar los problemas de concurrencia.

usuario1050755
fuente
3

Sincronizado simplemente significa que múltiples hilos si están asociados con un solo objeto pueden evitar la lectura y escritura sucias si se usa un bloque sincronizado en un objeto en particular. Para darle más claridad, tomemos un ejemplo:

class MyRunnable implements Runnable {
    int var = 10;
    @Override
    public void run() {
        call();
    }

    public void call() {
        synchronized (this) {
            for (int i = 0; i < 4; i++) {
                var++;
                System.out.println("Current Thread " + Thread.currentThread().getName() + " var value "+var);
            }
        }
    }
}

public class MutlipleThreadsRunnable {
    public static void main(String[] args) {
        MyRunnable runnable1 = new MyRunnable();
        MyRunnable runnable2 = new MyRunnable();
        Thread t1 = new Thread(runnable1);
        t1.setName("Thread -1");
        Thread t2 = new Thread(runnable2);
        t2.setName("Thread -2");
        Thread t3 = new Thread(runnable1);
        t3.setName("Thread -3");
        t1.start();
        t2.start();
        t3.start();
    }
}

Hemos creado dos objetos de clase MyRunnable, runnable1 se comparte con el hilo 1 y el hilo 3 y runnable2 se comparte solo con el hilo 2. Ahora, cuando t1 y t3 se inician sin que se use sincronizado, la salida PFB sugiere que ambos subprocesos 1 y 3 afectan simultáneamente el valor de var, donde para el subproceso 2, var tiene su propia memoria.

Without Synchronized keyword

    Current Thread Thread -1 var value 11
    Current Thread Thread -2 var value 11
    Current Thread Thread -2 var value 12
    Current Thread Thread -2 var value 13
    Current Thread Thread -2 var value 14
    Current Thread Thread -1 var value 12
    Current Thread Thread -3 var value 13
    Current Thread Thread -3 var value 15
    Current Thread Thread -1 var value 14
    Current Thread Thread -1 var value 17
    Current Thread Thread -3 var value 16
    Current Thread Thread -3 var value 18

Usando Synchronzied, thread 3 esperando que se complete el thread 1 en todos los escenarios. Hay dos bloqueos adquiridos, uno en runnable1 compartido por el hilo 1 y el hilo 3 y otro en runnable2 compartido solo por el hilo 2.

Current Thread Thread -1 var value 11
Current Thread Thread -2 var value 11
Current Thread Thread -1 var value 12
Current Thread Thread -2 var value 12
Current Thread Thread -1 var value 13
Current Thread Thread -2 var value 13
Current Thread Thread -1 var value 14
Current Thread Thread -2 var value 14
Current Thread Thread -3 var value 15
Current Thread Thread -3 var value 16
Current Thread Thread -3 var value 17
Current Thread Thread -3 var value 18
paras4all
fuente
Sincronizado significa aún más que eso: tiene un profundo impacto en la barrera de la memoria.
user1050755
1

Sincronizado simple significa que no hay dos hilos que puedan acceder al bloque / método simultáneamente. Cuando decimos que cualquier bloque / método de una clase está sincronizado, significa que solo un hilo puede acceder a ellos a la vez. Internamente, el subproceso que intenta acceder primero se bloquea en ese objeto y mientras este bloqueo no esté disponible, ningún otro subproceso puede acceder a ninguno de los métodos / bloques sincronizados de esa instancia de la clase.

Tenga en cuenta que otro hilo puede acceder a un método del mismo objeto que no está definido para sincronizarse. Un hilo puede liberar el bloqueo llamando

Object.wait()
Aniket Thakur
fuente
0

synchronizedEl bloque en Java es un monitor en subprocesamiento múltiple. synchronizedEl bloque con el mismo objeto / clase se puede ejecutar con un solo hilo, todos los demás están esperando. Puede ayudar con la race conditionsituación cuando varios hilos intentan actualizar la misma variable (el primer paso es usar volatileAcerca de )

Java 5extendido synchronizedapoyando happens-before[Acerca de]

Se produce un desbloqueo (bloqueo sincronizado o salida de método) de un monitor antes de cada bloqueo posterior (bloqueo sincronizado o entrada de método) de ese mismo monitor.

El siguiente paso es java.util.concurrent

volátil vs sincronizado

yoAlex5
fuente
-6

sincronizado es una palabra clave en Java que se usa para que ocurra antes de la relación en un entorno de subprocesos múltiples para evitar inconsistencias de memoria y errores de interferencia de subprocesos.

Sharad
fuente