Ein Beispiel, an das ich denken kann, ist das Szenario mit Tisch, Taschenlampe und Batterien. Stellen Sie sich eine Taschenlampe und ein Paar Batterien auf einem Tisch vor. Wenn Sie zu diesem Tisch gehen und die Batterien greifen, während eine andere Person die Taschenlampe hat, werden Sie beide gezwungen sein, sich unbeholfen anzustarren, während Sie darauf warten, wer ihren Gegenstand zuerst wieder auf den Tisch legt. Dies ist ein Beispiel für einen Deadlock. Sie und die Person warten auf Ressourcen, aber keiner von Ihnen gibt ihre Ressourcen auf.
In ähnlicher Weise tritt in einem Programm ein Deadlock auf, wenn zwei oder mehr Threads (Sie und die andere Person) darauf warten, dass zwei oder mehr Sperren (Taschenlampe und Batterien) freigegeben werden, und die Umstände im Programm so sind, dass die Sperren niemals freigegeben werden ( Sie haben beide ein Puzzleteil).
Wenn Sie Java kennen, können Sie dieses Problem folgendermaßen darstellen:
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();
}
}
Wenn Sie dieses Beispiel ausführen, werden Sie feststellen, dass die Dinge manchmal gut und korrekt funktionieren. Aber manchmal druckt Ihr Programm einfach nichts. Das liegt daran, dass eine Person die Batterien hat, während eine andere Person die Taschenlampe hat, die verhindert, dass sie die Taschenlampe einschaltet, was zu einem Deadlock führt.
Dieses Beispiel ähnelt dem Beispiel in den Java-Tutorials: http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html
Ein weiteres Beispiel ist das Schleifenbeispiel:
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();
}
}
Dieses Beispiel kann entweder immer wieder "Nicht erledigt" drucken oder es kann niemals "Nicht erledigt" drucken. Der erste geschieht, weil der erste Thread die Klassensperre erhält und sie niemals aufhebt, um zu verhindern, dass der zweite Thread auf 'stopLoop' zugreift. Und das Neueste passiert, weil der zweite Thread vor dem ersten Thread gestartet wurde und die Variable 'done' wahr ist, bevor der erste Thread ausgeführt wird.