Un exemple auquel je peux penser est le scénario Table, lampe de poche et piles. Imaginez une lampe de poche et une paire de piles placées sur une table. Si vous vous dirigez vers cette table et attrapez les piles pendant qu'une autre personne a la lampe de poche, vous serez tous les deux obligés de vous regarder maladroitement en attendant qui remettra en premier son article sur la table. Ceci est un exemple de blocage. Vous et la personne attendez des ressources, mais aucun de vous n'abandonne sa ressource.
De même, dans un programme, un blocage se produit lorsque deux ou plusieurs threads (vous et l'autre personne) attendez que deux verrous ou plus (lampe de poche et piles) soient libérés et que les circonstances du programme sont telles que les verrous ne sont jamais libérés ( vous avez tous les deux une pièce du puzzle).
Si vous connaissez java, voici comment vous pouvez représenter ce problème:
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 vous exécutez cet exemple, vous remarquerez que parfois les choses fonctionnent correctement et correctement. Mais parfois, votre programme n'imprimera rien. C'est parce qu'une personne a les piles tandis qu'une autre personne a la lampe de poche qui les empêche d'allumer la lampe de poche provoquant une impasse.
Cet exemple est similaire à l'exemple donné par les tutoriels java: http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html
Un autre exemple est l'exemple de boucle:
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();
}
}
Cet exemple peut soit imprimer «Non terminé» à plusieurs reprises, soit ne jamais afficher du tout «Non terminé». Le premier se produit parce que le premier thread acquiert le verrou de classe et ne le libère jamais, empêchant l'accès à 'stopLoop' par le second thread. Et le dernier se produit parce que le deuxième thread a démarré avant le premier thread, ce qui fait que la variable 'done' est vraie avant que le premier thread ne s'exécute.