Pregunta

Tengo algunas preguntas sobre el uso y la importancia del 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?
¿Fue útil?

Solución

El synchronized La palabra clave se trata de 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 habilitan una estrategia simple para prevenir la interferencia de los hilos y los errores de consistencia de la memoria:Si un objeto es visible para más de un hilo, todas las lecturas o escritas en las variables de ese objeto se realizan a través de métodos sincronizados.

En pocas palabras: Cuando tiene dos subprocesos que leen y escriben en el mismo 'recurso', digamos una variable llamada foo, debe asegurarse de que estos subprocesos accedan a la variable de forma atómica.Sin el synchronized palabra clave, es posible que su hilo 1 no vea el cambio realizado en el hilo 2 foo, o peor aún, es posible que solo se haya cambiado a medias.Esto no sería lo que lógicamente esperarías.

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

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

Otros consejos

Bueno, creo que hemos tenido bastante de las explicaciones teóricas, así que considere el 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: Los bloques synchronized llamado de la siguiente hilo método de ensayo (), siempre y cuando la ejecución del hilo anterior no ha terminado. Los temas pueden acceder a este método uno a la vez. Sin synchronized todas las discusiones pueden acceder a este método de forma simultánea.

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

Algo similar sucede cuando se llama a cualquier método sincronizado estático de la clase. El hilo adquiere el bloqueo asociado con la clase (en este caso cualquier método no estático sincronizado de una instancia de esa clase puede ser llamado por cualquier hilo porque esa cerradura nivel objeto todavía está disponible). Cualquier otro hilo no será capaz de llamar a cualquier método sincronizado estático de la clase, siempre y cuando la cerradura nivel de clase no se libera por el hilo que actualmente ocupa la cerradura.

Salida con sincronizada

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

La palabra clave synchronized impide el acceso simultáneo a un bloque de código o un objeto por múltiples hilos. Por defecto, un Hashtable es synchronized, por lo que sólo un hilo puede acceder a la tabla a la vez.

El uso de non-synchronized construye como HashMap, debe generar las características de seguridad de rosca en su código para evitar errores de coherencia de memoria.

synchronized significa que en un entorno multihilo, un método de objeto que tiene synchronized (s) / bloque (s) no permite que dos hilos para acceder al método (s) synchronized / bloque (s) de código al mismo tiempo. Esto significa que un hilo no puede leer, mientras que otro hilo lo actualiza.

El segundo hilo en su lugar esperar hasta la primera rosca completa su ejecución. La sobrecarga es la velocidad, pero la ventaja se garantiza la coherencia de los datos.

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

La palabra clave synchronized provoca un hilo para obtener un bloqueo al entrar en el método, de modo que sólo un hilo puede ejecutar el método al mismo tiempo (para la instancia de objeto determinada, a menos que sea un método estático).

Esto se llama hacer con frecuencia la clase thread-safe, pero yo diría que esto es un eufemismo. Si bien es cierto que la sincronización protege el estado interno del vector de conseguir dañado, esto no suele ayudar al usuario del vector mucho.

Considere esto:

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

A pesar de que los métodos implicados están sincronizados, porque están siendo bloqueados y desbloqueados de forma individual, dos hilos por desgracia cronometrados pueden crear un vector con dos elementos.

Así pues, en efecto, tiene que sincronizar en el código de aplicación también.

Debido sincronización a nivel de método es a) caro cuando se no lo necesita y b) insuficiente cuando se necesita sincronización, ahora hay reemplazos de un-sincronizado (ArrayList en el caso de vector).

Más recientemente, el paquete de concurrencia ha sido puesto en libertad, con una serie de utilidades inteligentes que se ocupan de cuestiones de multi-threading.

Descripción

palabra clave sincronizada en Java tiene que ver con el hilo de seguridad, es decir, cuando varios subprocesos leer o escribir la misma variable.
Esto puede ocurrir directamente (mediante el acceso a la misma variable) o indirectamente (mediante el uso de una clase que utiliza otra clase que tiene acceso a la misma variable).

La palabra clave sincronizada se utiliza para definir un bloque de código en la que múltiples hilos pueden tener acceso a la misma variable de una manera segura.

Deeper

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

  • Cuando la ejecución se encuentra con esta palabra clave, el subproceso actual trata de "bloqueo / adquisición / propia" (se quiera) el objeto de bloqueo y ejecutar el bloque asociado de código después de la cerradura tiene sido adquirida.

  • Cualquier escrituras en variables dentro del bloque de código sincronizado se garantiza que sea visible para todos los demás hilo que de igual forma se ejecuta código dentro de un bloque de código sincronizado con el mismo objeto de bloqueo .

  • Sólo un hilo a la vez puede mantener el bloqueo, tiempo durante el cual todos los otros hilos que tratan de adquirir el mismo objeto de bloqueo esperarán (pausar su ejecución). El bloqueo se libera cuando la ejecución sale del bloque de código sincronizado.

métodos sincronizados:

Adición palabra clave synchronized a una definición del 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) .

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

.

Técnica

Sin sincronización, no se garantiza el orden en que la lectura y escritura suceda, posiblemente dejando la variable con la 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 tratado de escribir, pero un lío combinado de ambas.)

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

Conclusión

Así, en el caso de Java, usted tiene que seguir el modelo de memoria de Java para asegurarse de que los errores de roscado no suceden.
En otras palabras:. El uso de sincronización, operaciones atómicas o clases que los utilizan para usted bajo las capuchas

  

Fuentes

     

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

Piense en ello como una especie de torniquete de que se puede encontrar en un campo de fútbol. Hay vapores paralelas de las personas que quieren entrar, pero en el torniquete que están 'sincronizados'. Sólo una persona a la vez puede pasar. Todos aquellos que quieran conseguir a través va a hacer, pero pueden tener que esperar hasta que puedan pasar.

  

¿Qué es la palabra clave sincronizada?

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

bloques o métodos sincronizados evita interferencia de rosca y asegurarse de que los datos es consistente. En cualquier punto de tiempo, sólo un hilo puede acceder a un bloque o método ( sección crítica ) sincronizada con la adquisición de una cerradura. Otro hilo (s) esperará liberación de bloqueo para acceder a sección crítica .

  

Cuando son métodos sincroniza?

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

  

¿Qué significa pro gramatical y lógicamente?

Esto significa que sólo un hilo puede tener acceso a sección crítica mediante la adquisición de una cerradura. A menos que este comunicado hilo este bloqueo, el resto del hilo (s) tendrá que esperar para adquirir un bloqueo. Ellos no tienen acceso para entrar sección crítica con el bloqueo de la adquisición a cabo.

Esto no se puede hacer con una magia. Es responsabilidad del programador para identificar sección (s) crítico en la aplicación y guárdela en consecuencia. Java proporciona un marco para proteger su aplicación, pero dónde y qué todas las secciones a estar protegidas es responsabilidad del programador.

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

intrínsecos Locks y sincronización:

  

Sincronización está construido alrededor de una entidad interna conocido como el bloqueo intrínseco o bloqueo del monitor. cerraduras intrínsecas juegan un papel en ambos aspectos de la sincronización:. la aplicación de acceso exclusivo al estado de un objeto y el establecimiento sucede-antes relaciones 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 bloqueo intrínseca del objeto antes de acceder a ellos, y luego liberar el bloqueo intrínseco cuando se hace con ellos.

Un hilo se dice que poseer la cerradura intrínseca entre el tiempo que se ha adquirido el bloqueo y liberada la cerradura. Mientras un hilo posee un bloqueo intrínseco, ningún otro hilo puede adquirir la misma cerradura. El otro hilo bloqueará cuando intenta adquirir el bloqueo.

  

Cuando un hilo libera un bloqueo intrínseco, una sucede-antes de establecer la relación entre la acción y cualquier posterior adquisición de la misma cerradura.

Fabricación de métodos sincronizados tiene dos efectos :

  

En primer lugar, no es posible que dos invocaciones de métodos sincronizados en 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 para el mismo bloque objeto (suspender la ejecución) sincronizados hasta la primera rosca se realiza con el objeto.

  

En segundo lugar, cuando un sincronizados salidas método, se establece automáticamente una sucede-antes relación con cualquier invocación subsiguiente de un método sincronizado para el mismo objeto.

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

buscar otras alternativas a la sincronización en:

Evitar sincronizado (este) en Java?

He aquí una explicación de Los Tutoriales de Java .

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 count es una instancia de SynchronizedCounter, a continuación, hacer estos métodos sincronizados tiene dos efectos:

     
      
  • primer lugar, no es posible que dos invocaciones de métodos sincronizados en 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 para el mismo bloque objeto (suspender la ejecución) sincronizados hasta la primera rosca se realiza con el objeto.
  •   
  • En segundo lugar, cuando un sincronizados salidas método, se establece automáticamente una sucede-antes relación con cualquier invocación subsiguiente de un método sincronizado para el mismo objeto. Esto garantiza que los cambios en el estado del objeto son visibles para todos los hilos.
  •   

Synchronized normal method equivalente aSynchronized statement (utilizar esta)

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

    equivalent to

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

Synchronized static method equivalente a Synchronized statement (usa clase)

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

    equivalent to

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

Declaración sincronizada (usando variable)

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

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

Para synchronized, tenemos ambos Synchronized Methods y Synchronized Statements.Sin embargo, Synchronized Methods es parecido a Synchronized Statements entonces solo 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 comprender. synchronized

  • Cada objeto/clase tiene un intrinsic lock asociado a ello.
  • Cuando un hilo invoca un synchronized statement, adquiere automáticamente el intrinsic lock para eso synchronized statement's objeto y lo libera cuando el método regresa.Mientras un hilo posea un intrinsic lock, Ninguna otra hilo puede adquirir el MISMO bloquear => hilo seguro.

=> Cuando un thread A invoca synchronized(this){// code 1} => todo el código de bloque (dentro de la clase) donde tiene synchronized(this) y todo synchronized normal method (dentro de la clase) está bloqueado porque MISMO cerrar con llave.Se ejecutará después thread A desbloquear ("// código 1" terminado).

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

MISMA CERRADURA => bloquear (¿no depende de qué método?o ¿qué declaraciones?)

¿Usar método sincronizado o declaraciones sincronizadas?

yo prefiero synchronized statements porque es más extensible.Por ejemplo, en el futuro, solo necesitará sincronizar una parte del método.Ejemplo, tienes 2 métodos sincronizados y no tengo ninguno relevantes entre sí, sin embargo, cuando un hilo 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 method para 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 usas synchronized o método normal o synchronized(this) o synchronized(non-static variable) se sincronizará en base a cada instancia de objeto.
  • cuando usas synchronized o método estático o synchronized(class) o synchronized(static variable) Se sincronizará según 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

A mi entender sincronizada básicamente significa que el compilador escribir Monitor.Enter y monitor.exit alrededor de su método. Como tal, puede ser seguro para subprocesos dependiendo de cómo se utiliza (lo que quiero decir es que usted puede escribir un objeto con métodos sincronizados que no está en hebras dependiendo de lo que hace su clase).

Lo que las otras respuestas faltan es un aspecto importante: barreras de memoria . la sincronización de hilos consiste básicamente en dos partes: la serialización y la visibilidad. Aconsejo a todos a Google de "barrera de la memoria JVM", ya que es un tema no trivial y muy importante (si modifica los datos compartidos accedidos por múltiples hilos). Una vez hecho esto, recomiendo mirar a las clases del paquete java.util.concurrent que ayudan a evitar el uso de la sincronización explícita, que a su vez ayuda a mantener los programas sencilla y eficiente, tal vez incluso la prevención de interbloqueos.

Un ejemplo de ello es ConcurrentLinkedDeque . Junto con el patrón de comando permite crear subprocesos de trabajo altamente eficientes por el relleno de los comandos en la cola concurrente -. ninguna sincronización explícita necesaria, no hay callejones sin salida posible, sin dormir explícita () es necesario, simplemente sondear la cola llamando toma ()

En pocas palabras: "la sincronización de la memoria" sucede implícitamente cuando se inicia un hilo, un extremos del hilo, se lee una variable volátil, se desbloquea un monitor (deje un bloque / función sincronizada), etc. Este "sincronización" afecta (en un sentido "vacía") todos de escrituras hechas antes de que la acción particular. En el caso de la ConcurrentLinkedDeque , la documentación "dice":

  

efectos de coherencia de la memoria: Al igual que con otras colecciones concurrentes,   acciones en un hilo antes de la colocación de un objeto en una   ConcurrentLinkedDeque suceder antes de las acciones posteriores al acceso   o la eliminación de ese elemento de la ConcurrentLinkedDeque en otro   hilo.

Este comportamiento implícito es un aspecto algo pernicioso porque la mayoría de los programadores de Java sin mucha experiencia se acaba de tomar una gran cantidad como se da a causa de ella. Y luego de repente tropezar sobre este tema después de Java no está haciendo lo que se "supone" que hacer en la producción donde hay una carga de trabajo diferente -. Y es bastante difícil de probar problemas de concurrencia

sincronizada simplemente significa que múltiples hilos si se asocia con el solo objeto pueden prevenir lectura sucia y escribir si bloque sincronizado se utiliza en particular, objeto. Para darle una mayor claridad, vamos a tomar 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 ser compartida con hilo 1 y el hilo 3 y runnable2 ser compartidos con rosca 2 solamente. Ahora, cuando t1 y t3 se inicia sin sincronizado que se utiliza, de salida PFB que sugieren que ambos hilos 1 y 3 que afecta simultáneamente valor var donde para el hilo 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

Uso Synchronzied, hilo 3 en espera de hilo 1 para completar en todos los escenarios. Hay dos bloqueos adquiridos, uno en runnable1 compartidos por hilo 1 y el hilo 3 y otro en runnable2 compartidos por hilo 2 solamente.

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

medios simples sincronizados no hay dos hilos pueden acceder al bloque / método simultáneamente. Cuando decimos que cualquier bloque / método de una clase está sincronizado que significa sólo un hilo puede acceder a ellos a la vez. Internamente, el hilo que intenta acceder a él primero tomar un bloqueo en ese objeto y siempre que este bloqueo no está disponible ningún otro hilo puede acceder a cualquiera de los métodos / sincronizados bloques de esa instancia de la clase.

Nota otro hilo puede acceder a un método del mismo objeto que no se define para ser sincronizado. Un hilo puede liberar el bloqueo llamando

Object.wait()

sincronizado es una palabra clave en Java que se utiliza para hacer que sucede antes de relación en multithreading medio ambiente para evitar incoherencias memoria y error interferencia de rosca.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top