JavaRush /Blog Java /Random-ES /¿Qué es el punto muerto en Java?
Alexey Smirnov
Nivel 29
Москва

¿Qué es el punto muerto en Java?

Publicado en el grupo Random-ES
Nivel de conocimiento requerido para comprender el artículo: ha completado las misiones Java Syntax y Java Core, y ahora está en el proceso de aprender Java Multithreading. Punto muerto o interbloqueo en Java o interbloqueo es un error que ocurre cuando los subprocesos tienen una dependencia cíclica de un par de objetos sincronizados. Imagine que un hilo ingresa al monitor de objetos xy el otro ingresa al monitor de objetos y. Si un hilo en un objeto xintenta llamar a cualquier método sincronizado en el objeto y, y el objeto yal mismo tiempo intenta llamar a cualquier método sincronizado en el objeto x, los hilos se atascarán esperando. ¿Qué es el punto muerto?  - 1A continuación se muestra un ejemplo del tutorial de documentos de Java sobre un concepto como interbloqueo. ¿Dónde ocurre el bloqueo de hilos aquí?
public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s" + "  has bowed to me!%n", this.name, bower.getName());
            bower.bowBack(this);
        }
        public synchronized void bowBack(Friend bower) {
            System.out.format("%s: %s"
                + " has bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    public static void main(String[] args) {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new Runnable() {
            @Override
            public void run() {
               // System.out.println("Thread 1");
                alphonse.bow(gaston);
               // System.out.println("Th: gaston bowed to alphonse");
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
              //  System.out.println("Thread 2");
                gaston.bow(alphonse);
              //  System.out.println("2.gaston waiting alph bowed");
            }
        }).start();
    }
}
Hay dos cosas importantes que entender aquí:
  1. ¿Qué hace exactamente cada uno de los subprocesos que se ejecutan simultáneamente?
  2. ¿Qué cerraduras se utilizan?
Empecemos por el final. Digamos que creaste dos objetos de la clase Friend: alphonsey gaston. Cada uno de ellos tiene su propia cerradura. Así, existen dos de estas cerraduras: gigolós y gastons. Cuando se ingresa a un método sincronizado de un objeto, su bloqueo se bloquea y cuando se sale del método, se libera (o desbloquea). Ahora sobre los hilos. Llamemos al primer hilo Alphonse(con mayúscula para distinguirlo del objeto alphonse). Esto es lo que hace (llamémoslo A, abreviatura de Alphonse):
A: alphonse.bow(gaston) — получает лок alphonse;
A: gaston.bowBack(alphonse) — получает лок gaston;
A: возвращается из обоих методов, тем самым освобождая лок.
Y esto es lo que está haciendo el hilo en este momento Gaston:
G: gaston.bow(alphonse) — получает лок gaston;
G: alphonse.bowBack(gaston) — получает лок alphonse;
G: возвращается из обоих методов, тем самым освобождая лок.
Ahora juntemos estos datos y obtengamos la respuesta. Los hilos se pueden entrelazar (es decir, sus eventos ocurrirán) en diferentes órdenes. Un punto muerto funcionará, por ejemplo, si el orden es el siguiente:
A: alphonse.bow(gaston) — получает лок alphonse
G: gaston.bow(alphonse) — получает лок gaston
G: пытается вызвать alphonse.bowBack(gaston), но блокируется, ожидая лока alphonse
A: пытается вызвать gaston.bowBack(alphonse), но блокируется, ожидая лока gaston
¿Qué es el punto muerto?  - 2
En este caso, ambos subprocesos están bloqueados y cada uno espera que el otro libere el bloqueo. Pero ninguno de ellos hará esto, porque para hacerlo necesitan completar su método, y otro hilo lo bloquea. Así que quedaron atrapados donde sucedió deadlock. Sin embargo, también es posible otro tejido, en el que uno de los hilos tendrá tiempo de completarse antes de que comience el segundo:
A: alphonse.bow(gaston) — получает лок alphonse
A: gaston.bowBack(alphonse) — получает лок gaston
A: возвращается из обоих методов, открывая оба лока
G: gaston.bow(alphonse) — получает лок gaston
G: alphonse.bowBack(gaston) — получает лок alphonse
G: возвращается из обоих методов, открывая оба лока
En este caso, no hay bloqueo mutuo de subprocesos. Por ejemplo, se ha agregado algún método que permite que otro hilo tenga tiempo para ejecutarse. Cuando el resultado depende del orden de los eventos que ocurren simultáneamente (orden planificado o velocidad de ejecución), dicho proceso en ruso se denomina condición de carrera - "condición de carrera". No todas las condiciones de carrera potencialmente causan un punto muerto; sin embargo, en mi experiencia, solo las condiciones de carrera causan punto muerto. Publicado por: Dave Lillethun
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION