9
Concurrence et interférences
Le programme ThreadInterferenceTest démarre l'exécution en parallèle de deux Threads. Le premier, le Maker, incrémente une variable 1000000 de fois. Le second, le Taker, décrémente la même variable 1000000 de fois aussi. À la fin, le programme affiche la valeur de la variable.
- public class ThreadInterferenceTest {
- static final private int NCALLS = 1000000;
- private int counter = 0;
- private Thread maker, taker;
- public ThreadInterferenceTest() {
- maker = new Thread(new Maker());
- taker = new Thread(new Taker());
- }
- public int getCounter() {
- return counter;
- }
- // MUST be synchonized
- public void inc() {
- counter++;
- }
- // MUST be synchonized
- public void dec() {
- counter--;
- }
- public void go() {
- maker.start();
- taker.start();
- try {
- maker.join();
- taker.join();
- }
- catch (InterruptedException e) {
- }
- }
- private class Maker implements Runnable {
- public void run() {
- for (int i = 0; i < NCALLS; i++)
- inc();
- }
- }
- private class Taker implements Runnable {
- public void run() {
- for (int i = 0; i < NCALLS; i++)
- dec();
- }
- }
- public static void main(String args[]) {
- ThreadInterferenceTest test = new ThreadInterferenceTest();
- test.go();
- System.out.println(test.getCounter());
- }
- }
$ javac ThreadInterferenceTest.java
$ java ThreadInterferenceTest
-92387
$ java ThreadInterferenceTest
-784617
Au lieu d'obtenir la valeur attendue, 0, le compteur affiche une valeur aléatoire. NOTE : Si vous obtenez 0, relancez le programme. Si nécessaire, augmentez le nombre d'appels en changeant la valeur de la constante NCALLS
.
Ajoutez le mot clé synchronized
devant le type de donnée retourné par inc
et dec
, entre public
et void
, pour demander à Java de veiller à ce que l'exécution de ces méthodes ne soit par interrompue.
- public synchronized void inc() {
- public synchronized void dec() {
$ javac ThreadInterferenceTest.java
$ java ThreadInterferenceTest
0
Commentaires