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
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ó
x
y el otro ingresa al monitor de objetos y
. Si un hilo en un objeto x
intenta llamar a cualquier método sincronizado en el objeto y
, y el objeto y
al mismo tiempo intenta llamar a cualquier método sincronizado en el objeto x
, los hilos se atascarán esperando. A 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í:
- ¿Qué hace exactamente cada uno de los subprocesos que se ejecutan simultáneamente?
- ¿Qué cerraduras se utilizan?
Friend
: alphonse
y 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
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
Qué más leer: |
---|
Grupo de desarrolladores de Java: Geniales optimizaciones de SQL que no dependen del modelo de costos. Parte 1 |
GO TO FULL VERSION