2011-07-05 8 views
10

Desde que comencé a programar en Java me he estado preguntando esto (alrededor de un año o dos). En C, debemos conocer el método diferente para evitar correctamente el punto muerto entre el hilo y, por lo tanto, hay mucha más opción entre el método de sincronización.¿Cómo funciona la funcionalidad de sincronización en Java?

¿Y qué hay de Java? Cuando sincronizamos, ¿cómo se evita poner hilo en una situación de estancamiento? ¿Cómo funciona internamente? ¿Se evita el punto muerto porque sincronizamos en un nivel más alto que en C (o C++)? ¿Alguna documentación sobre interbloqueo y sincronización en Java?

Respuesta

0

También tiene que encargarse de los bloqueos en Java. La forma más fácil de obtener un punto muerto es hacer que un hilo ejecute un bloque sincronizado en A, y luego otro bloque sincronizado en B, mientras que otro hilo ejecuta un bloque sincronizado en B y luego un bloque sincronizado en A.

Leer the Java tutorial about concurrency. Y si quieres seguir aprendiendo, lee Java concurrency in practice.

1

sincronización no es realmente mucho más fácil en Java que en C sintácticamente es más fácil, porque todo lo que necesita hacer para un mutex es declarar un método como el sincronizada o utilizar

synchronized(someObject) 
{ 
    someCode(); 
} 

Mientras que en C/C++, tiene que usar funciones específicas del sistema operativo para usar un mutex, o tiene que usar la biblioteca de Boost.

Pero las trampas sobre el punto muerto son básicamente las mismas que en cualquier idioma.

+0

¡Gracias! Pero, ¿qué significa exactamente la palabra clave sincronizada, es un mutex? Y en diferentes plataformas, dado que los hilos pueden ser diferentes, ¿también será diferente? – Zonata

+2

Es un mutex. Un mutex reentrante. –

0

¿Has probado google (Java Deadlock)? El primer resultado es este: http://download.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

Allí se puede ver que con synchronized se producen bloqueos, ya que la sincronización no está diseñada para evitarlos en primer lugar.

+0

Bueno, el objetivo de mi pregunta no es solo acerca del punto muerto. Sé cuál es el punto muerto y conozco la mayoría del problema bien conocido (cena de filósofos, etc.). También se trata de la funcionalidad interna de la palabra clave sincronizada. Quiero saber más detalles sobre cómo funciona. – Zonata

+0

@Zonata ¿Entonces echó un vistazo a los documentos de Oracle sobre la sincronización? Es solo un capítulo antes del punto muerto que ligé. La respuesta se adaptó principalmente a esta pregunta: 'Cuando sincronizamos, ¿cómo se evita poner hilo en la situación de estancamiento?' - No es así. – Thomas

5

El principal problema que encontramos con un código multiproceso es el intercambio de datos, y estoy de acuerdo con el propósito del proceso de paralelismos de concurencia y ocurre "ocasionalmente" que durante el procesamiento paralizado que los hilos necesitan acceso para leer/escribir datos compartidos.

Los java palabra clave sincronizados facilita las siguientes funciones:

Cuenta la JVM para poner un candado en el monitor del objeto o de la pieza del código sincronizado, lo que le da acceso exclusivo a esa parte del código o un objeto .

He aquí un ejemplo de un Singleton:

public class Singleton { 
    private Singleton INSTANCE; 

    private Singleton() { 
    } 

    public Singleton getInstance() { 
     if (null == INSTANCE) { 
      INSTANCE = new Singleton(); 
     } 
     return INSTANCE; 
    } 
} 

Este Singleton no es seguro para subprocesos, si un hilo está tratando de obtener una instancia mientras que otro también está tratando de hacer lo mismo (condición de carrera) se Puede suceder que antes de que el hilo número uno termine la creación de la instancia, el segundo ya haya tenido acceso al método getInstance() y haya creado su propia instancia de Singleton, lo que significa que en un tiempo T deberíamos tener dos instancias del Singleton (llamado multitón en ese momento).

Para resolver este problema que tenemos para sincronizar el comportamiento creacional del singleton, esto se puede hacer por la palabra clave synchronized por encima de la sentencia if en la INSTANCE sí:

public class Singleton { 
    private Singleton INSTANCE; 

    private Singleton() { 
    } 

    public Singleton getInstance() { 
     synchronized (Singleton.class) { 
      if (null == INSTANCE) { 
       synchronized(Singleton.class) { 
        Singleton inst = new Singleton(); 
        INSTANCE = inst; 
       } 
      } 
     } 
     return INSTANCE; 
    } 
} 

El resultado es que el primer hilo pregunta a la instancia de Singleton y durante el tiempo de creación, la JVM pondrá un candado en el monitor de la INSTANCIA denegando cualquier acceso a la INSTANCIA hasta que el hilo uno finalice su solicitud.

Hay diferentes maneras de lograr eso también, el libro citado anteriormente es una excelente fuente de aprendizaje, javadoc también.

1

respuestas cortas:

  1. synchronized métodos y lock bloques utilizan un monitorque bloquea el semáforo del objeto bloqueado para la duración del método o bloque.

  2. El lenguaje Java en sí no evita los bloqueos. Depende de usted, como programador, asegurarse de que los objetos estén bloqueados/desbloqueados en el orden correcto para evitar conflictos.

0

Veo algún problema con Singleton anterior. Creo que esa clase nunca se creará. Por favor considere el siguiente código.

public class Singleton { 
    private static Singleton INSTANCE; 
    private Singleton() {  } 
    public static Singleton getInstance() { 
     synchronized (Singleton.class) { 
      if (null == INSTANCE) { 
       synchronized(Singleton.class) { 
        Singleton inst = new Singleton(); 
        INSTANCE = inst; 
        } 
      } 
     } 
     return INSTANCE; 
    } 
} 
+1

¿Por qué la clase no se creará nunca? –

Cuestiones relacionadas