Java Thread - Exemple de Mutex et de sémaphore
Exemple Java multi threads pour vous montrer comment utiliserSemaphore etMutex pour limiter le nombre de threads pour accéder aux ressources.
-
Semaphores- Restreint le nombre de threads pouvant accéder à une ressource. Exemple, limitez 10 connexions maximum pour accéder simultanément à un fichier. -
Mutex- Un seul thread pour accéder à une ressource à la fois. Par exemple, lorsqu'un client accède à un fichier, personne d'autre ne doit avoir accès au même fichier en même temps.
1. Sémaphore
Considérons une cabine ATM avec 4 distributeurs automatiques,Semaphore peut s'assurer que seulement 4 personnes peuvent accéder simultanément.
SemaphoreTest.java
package com.techfou;
import java.util.concurrent.Semaphore;
public class SemaphoreTest {
// max 4 people
static Semaphore semaphore = new Semaphore(4);
static class MyATMThread extends Thread {
String name = "";
MyATMThread(String name) {
this.name = name;
}
public void run() {
try {
System.out.println(name + " : acquiring lock...");
System.out.println(name + " : available Semaphore permits now: "
+ semaphore.availablePermits());
semaphore.acquire();
System.out.println(name + " : got the permit!");
try {
for (int i = 1; i <= 5; i++) {
System.out.println(name + " : is performing operation " + i
+ ", available Semaphore permits : "
+ semaphore.availablePermits());
// sleep 1 second
Thread.sleep(1000);
}
} finally {
// calling release() after a successful acquire()
System.out.println(name + " : releasing lock...");
semaphore.release();
System.out.println(name + " : available Semaphore permits now: "
+ semaphore.availablePermits());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
System.out.println("Total available Semaphore permits : "
+ semaphore.availablePermits());
MyATMThread t1 = new MyATMThread("A");
t1.start();
MyATMThread t2 = new MyATMThread("B");
t2.start();
MyATMThread t3 = new MyATMThread("C");
t3.start();
MyATMThread t4 = new MyATMThread("D");
t4.start();
MyATMThread t5 = new MyATMThread("E");
t5.start();
MyATMThread t6 = new MyATMThread("F");
t6.start();
}
}
La sortie peut varier, mais le flux de verrouillage et de libération doit être plus ou moins le même.
Total available Semaphore permits : 4 A : acquiring lock... D : acquiring lock... C : acquiring lock... B : acquiring lock... B : available Semaphore permits now: 4 C : available Semaphore permits now: 4 E : acquiring lock... F : acquiring lock... F : available Semaphore permits now: 2 F : got the permit! F : is performing operation 1, available Semaphore permits : 1 D : available Semaphore permits now: 4 A : available Semaphore permits now: 4 D : got the permit! D : is performing operation 1, available Semaphore permits : 0 E : available Semaphore permits now: 2 C : got the permit! B : got the permit! C : is performing operation 1, available Semaphore permits : 0 B : is performing operation 1, available Semaphore permits : 0 F : is performing operation 2, available Semaphore permits : 0 D : is performing operation 2, available Semaphore permits : 0 C : is performing operation 2, available Semaphore permits : 0 B : is performing operation 2, available Semaphore permits : 0 F : is performing operation 3, available Semaphore permits : 0 D : is performing operation 3, available Semaphore permits : 0 C : is performing operation 3, available Semaphore permits : 0 B : is performing operation 3, available Semaphore permits : 0 F : is performing operation 4, available Semaphore permits : 0 D : is performing operation 4, available Semaphore permits : 0 C : is performing operation 4, available Semaphore permits : 0 B : is performing operation 4, available Semaphore permits : 0 D : is performing operation 5, available Semaphore permits : 0 F : is performing operation 5, available Semaphore permits : 0 B : is performing operation 5, available Semaphore permits : 0 C : is performing operation 5, available Semaphore permits : 0 D : releasing lock... F : releasing lock... D : available Semaphore permits now: 1 A : got the permit! A : is performing operation 1, available Semaphore permits : 0 F : available Semaphore permits now: 1 E : got the permit! E : is performing operation 1, available Semaphore permits : 0 B : releasing lock... B : available Semaphore permits now: 1 C : releasing lock... C : available Semaphore permits now: 2 A : is performing operation 2, available Semaphore permits : 2 E : is performing operation 2, available Semaphore permits : 2 A : is performing operation 3, available Semaphore permits : 2 E : is performing operation 3, available Semaphore permits : 2 A : is performing operation 4, available Semaphore permits : 2 E : is performing operation 4, available Semaphore permits : 2 A : is performing operation 5, available Semaphore permits : 2 E : is performing operation 5, available Semaphore permits : 2 A : releasing lock... A : available Semaphore permits now: 3 E : releasing lock... E : available Semaphore permits now: 4
Observez attentivement la sortie ci-dessus, vous verrez qu'il y a maximum 4 personnes (C, B, F, D) pour effectuer une opération à la fois, les personnes A et E sont en attente. Dès que l'un d'eux libère le verrou (D et F), A et E l'acquièrent et le reprennent immédiatement.
2. Mutex
Mutex est leSemaphore avec un nombre d'accès de 1. Considérez une situation d'utilisation de casiers à la banque. Habituellement, la règle est qu'une seule personne est autorisée à entrer dans les vestiaires.
MutexTest.java
package com.techfou;
import java.util.concurrent.Semaphore;
public class SemaphoreTest {
// max 1 people
static Semaphore semaphore = new Semaphore(1);
static class MyLockerThread extends Thread {
String name = "";
MyLockerThread(String name) {
this.name = name;
}
public void run() {
try {
System.out.println(name + " : acquiring lock...");
System.out.println(name + " : available Semaphore permits now: "
+ semaphore.availablePermits());
semaphore.acquire();
System.out.println(name + " : got the permit!");
try {
for (int i = 1; i <= 5; i++) {
System.out.println(name + " : is performing operation " + i
+ ", available Semaphore permits : "
+ semaphore.availablePermits());
// sleep 1 second
Thread.sleep(1000);
}
} finally {
// calling release() after a successful acquire()
System.out.println(name + " : releasing lock...");
semaphore.release();
System.out.println(name + " : available Semaphore permits now: "
+ semaphore.availablePermits());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
System.out.println("Total available Semaphore permits : "
+ semaphore.availablePermits());
MyLockerThread t1 = new MyLockerThread("A");
t1.start();
MyLockerThread t2 = new MyLockerThread("B");
t2.start();
MyLockerThread t3 = new MyLockerThread("C");
t3.start();
MyLockerThread t4 = new MyLockerThread("D");
t4.start();
MyLockerThread t5 = new MyLockerThread("E");
t5.start();
MyLockerThread t6 = new MyLockerThread("F");
t6.start();
}
}
La sortie peut varier, mais le flux de verrouillage et de libération doit être le même.
Total available Semaphore permits : 1 A : acquiring lock... B : acquiring lock... A : available Semaphore permits now: 1 C : acquiring lock... B : available Semaphore permits now: 1 C : available Semaphore permits now: 0 A : got the permit! D : acquiring lock... E : acquiring lock... A : is performing operation 1, available Semaphore permits : 0 E : available Semaphore permits now: 0 D : available Semaphore permits now: 0 F : acquiring lock... F : available Semaphore permits now: 0 A : is performing operation 2, available Semaphore permits : 0 A : is performing operation 3, available Semaphore permits : 0 A : is performing operation 4, available Semaphore permits : 0 A : is performing operation 5, available Semaphore permits : 0 A : releasing lock... A : available Semaphore permits now: 1 B : got the permit! B : is performing operation 1, available Semaphore permits : 0 B : is performing operation 2, available Semaphore permits : 0 B : is performing operation 3, available Semaphore permits : 0 B : is performing operation 4, available Semaphore permits : 0 B : is performing operation 5, available Semaphore permits : 0 B : releasing lock... B : available Semaphore permits now: 1 C : got the permit! C : is performing operation 1, available Semaphore permits : 0 C : is performing operation 2, available Semaphore permits : 0 C : is performing operation 3, available Semaphore permits : 0 C : is performing operation 4, available Semaphore permits : 0 C : is performing operation 5, available Semaphore permits : 0 C : releasing lock... C : available Semaphore permits now: 1 E : got the permit! E : is performing operation 1, available Semaphore permits : 0 E : is performing operation 2, available Semaphore permits : 0 E : is performing operation 3, available Semaphore permits : 0 E : is performing operation 4, available Semaphore permits : 0 E : is performing operation 5, available Semaphore permits : 0 E : releasing lock... E : available Semaphore permits now: 1 D : got the permit! D : is performing operation 1, available Semaphore permits : 0 D : is performing operation 2, available Semaphore permits : 0 D : is performing operation 3, available Semaphore permits : 0 D : is performing operation 4, available Semaphore permits : 0 D : is performing operation 5, available Semaphore permits : 0 D : releasing lock... D : available Semaphore permits now: 1 F : got the permit! F : is performing operation 1, available Semaphore permits : 0 F : is performing operation 2, available Semaphore permits : 0 F : is performing operation 3, available Semaphore permits : 0 F : is performing operation 4, available Semaphore permits : 0 F : is performing operation 5, available Semaphore permits : 0 F : releasing lock... F : available Semaphore permits now: 1
Comme on peut le voir, un seul thread s'exécute à la fois ici. C'est le rôle d'un Mutex.