Pregunta ¿Qué significa 'sincronizado'?


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

  • ¿Cuál es el significado de la synchronized ¿palabra clave?
  • Cuándo deberían ser los métodos synchronized?
  • ¿Qué significa programática y lógicamente?

818
2017-07-06 06:47


origen


Respuestas:


los synchronized la palabra clave se trata de diferentes hilos que leen y escriben a las mismas variables, objetos y recursos. Este no es un tema trivial en Java, pero aquí hay una cita de Sun:

synchronized métodos permiten un simple   estrategia para prevenir el hilo   interferencia y consistencia de la memoria   errores: si un objeto es visible para   más de un hilo, todas las lecturas o   escribe a las variables de ese objeto son   hecho a través de métodos sincronizados.

En pocas palabras: Cuando tiene dos hilos que están leyendo y escribiendo en el mismo 'recurso', diga una variable llamada foo, debe asegurarse de que estos subprocesos accedan a la variable de forma atómica. Sin el synchronized palabra clave, su subproceso 1 puede no ver el cambio de subproceso 2 hecho a fooo, lo que es peor, solo puede ser medio cambiado. Esto no sería lo que lógicamente esperas.

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

Sigue explorando estos temas hasta que el nombre "Brian Goetz" se asocia permanentemente con el término "concurrencia" en tu cerebro


749
2017-07-06 07:01



Bueno, creo que 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: synchronized bloquea la llamada del siguiente subproceso a la prueba de método () siempre que la ejecución del subproceso anterior no haya finalizado. Los subprocesos pueden acceder a este método de a uno por vez. Sin synchronized todos los hilos pueden acceder a este método simultáneamente.

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

Algo similar sucede cuando se llama a cualquier método estático sincronizado de la clase. El hilo adquiere el bloqueo asociado a la clase (en este caso, cualquier subproceso no estático sincronizado de una instancia de esa clase puede invocarse mediante cualquier subproceso porque ese bloqueo de nivel de objeto aún está disponible). Cualquier otro hilo no podrá llamar a ningún método estático sincronizado de la clase, siempre que el bloqueo de nivel de clase no sea liberado por el hilo que actualmente contiene el bloqueo.

Salida con sincronización

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 sincronización

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

244
2018-05-15 13:23



los synchronized La palabra clave previene el acceso concurrente a un bloque de código u objeto por múltiples hilos. Por defecto, una Hashtable es synchronized, por lo que solo un hilo puede acceder a la tabla a la vez.

En el uso de non-synchronized construcciones como HashMap, debe crear características de seguridad de subprocesos en su código para evitar errores de coherencia de memoria.


102
2018-01-22 18:39



synchronizedsignifica que en un entorno de múltiples hilos, un objeto que tiene synchronized método (s) / bloque (es) no permite que dos hilos para acceder al synchronized mé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 coherencia garantizada de los datos.

Si su aplicación es de un solo hilo, synchronized bloques no proporciona beneficios.


73
2018-01-22 18:39



los synchronized La palabra clave hace que un hilo obtenga un bloqueo al ingresar el método, de modo que solo un hilo pueda ejecutar el método al mismo tiempo (para la instancia del objeto dado, a menos que sea un método estático).

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

Considera esto:

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

Aunque los métodos involucrados están sincronizados, porque están siendo bloqueados y desbloqueados individualmente, dos hilos desafortunadamente temporizados pueden crear un vector con dos elementos.

Entonces, en efecto, también tiene que sincronizarse en el código de la 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 varias utilidades inteligentes que se encargan de los problemas de subprocesos múltiples.


50
2017-07-06 07:09



Visión de conjunto

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 forma segura.

Más adentro

Sintaxis sabia synchronized palabra clave toma una Object como su parámetro (llamado un objeto de bloqueo), que es seguido por un { block of code }.

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

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

  • Solo un hilo a la vez puede mantener el bloqueo, y durante ese tiempo todos los otros hilos que intentan adquirir el mismo objeto de bloqueo esperará (pausa su ejecución). El bloqueo se liberará cuando la ejecución salga del bloque de código sincronizado.

Métodos sincronizados:

Añadiendo synchronized palabra clave para una definición de método es igual a todo el cuerpo del método envuelto en un bloque de código sincronizado con el objeto de bloqueosiendo this  (por ejemplo, métodos) y ClassInQuestion.getClass()  (para los métodos de clase).

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

Técnico

Sin sincronización, no está garantizado el orden en que 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 subproceso y la mitad de los bits escritos por otro subproceso, dejando la variable en un estado que ninguno de los subprocesos intentó escribir, sino un desorden combinado de ambos).

No es suficiente completar una operación de escritura en un hilo antes (hora del reloj de pared) otro hilo lo lee, porque el hardware podría haber almacenado el valor de la variable en caché y el hilo de lectura vería el valor en caché en lugar de lo escrito 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 utilicen por usted debajo de las capuchas.

Fuentes

http://docs.oracle.com/javase/specs/jls/se8/html/index.html
Especificación del lenguaje Java, 2015-02-13


20
2018-06-22 15:19



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 quieren 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.


18
2017-07-06 07:09



¿Cuál es la palabra clave sincronizada?

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

Los bloques o métodos sincronizados evitan la interferencia de hilos y garantizan que los datos sean consistentes. En cualquier punto del tiempo, solo un hilo puede acceder a un bloque o método sincronizado (sección crítica) al adquirir un candado. Otro (s) hilo (s) esperarán a la liberación del bloqueo para acceder sección crítica.

¿Cuándo se sincronizan los métodos?

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

¿Qué significa pro gramatical y lógicamente?

Significa que solo un hilo puede acceder sección crítica adquiriendo un candado A menos que este hilo libere este bloqueo, todos los demás hilos tendrán que esperar para adquirir un bloqueo. No tienen acceso para ingresar sección crítica sin cerradura de adquisición.

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

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

Cerraduras intrínsecas y sincronización:

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

Cada objeto tiene un bloqueo intrínseco asociado a él. 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 termina con ellos.

Se dice que un hilo posee el bloqueo intrínseco entre el momento en que ha adquirido el bloqueo y liberado el bloqueo. Siempre que 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 de pase previo entre esa acción y cualquier adquisición posterior del mismo bloqueo.

Hacer que los métodos estén sincronizados tiene dos efectos:

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

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.

En segundo lugar, cuando sale un método sincronizado, establece automáticamente una relación de pasar antes 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?


11
2017-12-14 06:56



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 puedes escribir un objeto con métodos sincronizados que no es seguro para las tareas en función de lo que haga tu clase).


6
2017-07-06 07:01