Un ejemplo en el que puedo pensar es el escenario Mesa, linterna y baterías. Imagina una linterna y un par de pilas colocadas encima de una mesa. Si tuvieras que caminar hasta esta mesa y agarrar las baterías mientras otra persona tiene la linterna, ambos se verán obligados a mirarse torpemente el uno al otro mientras esperan quién colocará primero su artículo en la mesa. Este es un ejemplo de punto muerto. Usted y la persona están esperando recursos, pero ninguno de ustedes está renunciando a su recurso.
De manera similar, en un programa, el interbloqueo ocurre cuando dos o más subprocesos (usted y la otra persona) están esperando que se liberen dos o más candados (linterna y baterías) y las circunstancias en el programa son tales que los candados nunca se liberan ( ambos tienen una pieza del rompecabezas).
Si conoce Java, así es como puede representar este problema:
import java.util.concurrent.locks.*;
public class Deadlock1 {
public static class Table {
private static Lock Flashlight = new ReentrantLock();
private static Lock Batteries = new ReentrantLock();
public static void giveFlashLightAndBatteries() {
try {
Flashlight.lock();
Batteries.lock();
System.out.println("Lights on");
} finally {
Batteries.unlock();
Flashlight.unlock();
}
}
public static void giveBatteriesAndFlashLight() {
try {
Batteries.lock();
Flashlight.lock();
System.out.println("Lights on");
} finally {
Flashlight.unlock();
Batteries.unlock();
}
}
}
public static void main(String[] args) {
// This thread represents person one
new Thread(new Runnable() {
public void run() { Table.giveFlashLightAndBatteries(); }
}).start();
// This thread represents person two
new Thread(new Runnable() {
public void run() { Table.giveBatteriesAndFlashLight(); }
}).start();
}
}
Si ejecuta este ejemplo, notará que a veces las cosas funcionan bien y correctamente. Pero a veces su programa simplemente no imprime nada. Esto se debe a que una persona tiene las baterías mientras que otra persona tiene la linterna, lo que les impide encender la linterna y provocar un bloqueo.
Este ejemplo es similar al ejemplo dado por los tutoriales de Java: http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html
Otro ejemplo es el ejemplo de bucle:
public class Deadlock2 {
public static class Loop {
private static boolean done = false;
public static synchronized void startLoop() throws InterruptedException {
while(!done) {
Thread.sleep(1000);
System.out.println("Not done");
}
}
public static synchronized void stopLoop() {
done = true;
}
}
public static void main(String[] args) {
// This thread starts the loop
new Thread(new Runnable() {
public void run() {
try {
Loop.startLoop();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
// This thread stops the loop
new Thread(new Runnable() {
public void run() {
Loop.stopLoop();
}
}).start();
}
}
Este ejemplo puede imprimir 'No hecho' una y otra vez o nunca puede imprimir 'No hecho' en absoluto. Lo primero ocurre porque el primer hilo adquiere el bloqueo de clase y nunca lo libera, lo que impide que el segundo hilo acceda a 'stopLoop'. Y lo último sucede porque el segundo hilo comenzó antes que el primer hilo, lo que hace que la variable 'done' sea verdadera antes de que se ejecute el primer hilo.