Les Threads en Java

Fermé
boualiasma Messages postés 393 Date d'inscription lundi 22 juin 2009 Statut Membre Dernière intervention 23 décembre 2011 - 11 oct. 2010 à 10:00
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 - 11 oct. 2010 à 12:30
Bonjour,

Je n'arrive pas à comprendre que fait le programme suivant :


public class VasesCommuniquants {
private static final int QUANTITE_INITIALE = 200;                  
public static final int NB_THREAD_MAX = 3;
private static int iteration =0;

private int []  vase = {QUANTITE_INITIALE/2, QUANTITE_INITIALE/2};

public VasesCommuniquants(){
for (int i=0;i < NB_THREAD_MAX;i++)
 new ThreadTransfert().start();
 }
 
 public static void main(String[] args) {
  new VasesCommuniquants();
 }
 
 public int transfert (int qte){
 System.out.println("-("+qte+") dans la vase 1");
 vase[0] -= qte;
   System.out.println("+("+qte+") dans la vase 2");
 vase[1] += qte;
  iteration ++;
if(iteration % 100 == 0)
   System.out.println(""+iteration+"itérations");
   return vase[0]+vase[1];
}

public class ThreadTransfer extends thread {
Random r = new Random ();
int quantite;
public void run(){
while(!isInterrupted()){
quantite= r.nextInt(1L)=6;
if(transfert(quantite) != QUANTITE_INITIALE) {
System.out.println("Quantité totale invalide à l'itérartion"+iteration);
system.exit(-1);
}

try {
      Thread.sleep(10);
    }catch (InterruptedException e) {}
 }
}


Je ne comprends pas comment interpéter les résultats trouvés dans ce programme ?

5 réponses

cs_jojolemariole Messages postés 519 Date d'inscription mercredi 21 mars 2007 Statut Membre Dernière intervention 19 décembre 2016 25
11 oct. 2010 à 10:30
Salut,

Je ne sais pas comment tu as réussi à compiler cette classe. Je vois plein d'erreurs.

Supposons que je parte de ce code :

import java.util.Random;

public class VasesCommuniquants {

    private static final int QUANTITE_INITIALE = 200;
    public static final int NB_THREAD_MAX = 3;
    private static int iteration = 0;

    private int[] vase = { QUANTITE_INITIALE / 2, QUANTITE_INITIALE / 2 };

    public VasesCommuniquants() {

        for (int i = 0; i < NB_THREAD_MAX; i++) {
            new ThreadTransfert().start();
        }

    }

    public static void main(String[] args) {
        new VasesCommuniquants();
    }

    public int transfert(int qte) {

        System.out.println("-(" + qte + ") dans la vase 1");
        vase[0] -= qte;
        System.out.println("+(" + qte + ") dans la vase 2");
        vase[1] += qte;

        iteration++;

        if (iteration % 100 == 0) {
            System.out.println("" + iteration + "itérations");
        }

        return vase[0] + vase[1];

    }

    public class ThreadTransfert extends Thread {

        Random r = new Random();
        int quantite;

        public void run() {

            while (!isInterrupted()) {

                quantite = 1 + r.nextInt(10);

                if (transfert(quantite) != QUANTITE_INITIALE) {

                    System.out
                            .println("Quantité totale invalide à l'itération "
                                    + iteration);

                    System.exit(-1);

                }

                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                }

            }

        }

    }

}


Apparemment ce code est censé effectuer des transferts entre 2 vases tout en vérifiant après chaque transfert que la quantité totale est correcte.

3 threads effectuant des transferts sont démarrés et fatalement au bout de quelques itérations, les threads se chevauchant dans la méthode transfert, la quantité totale est incorrecte.

En règle générale, il faut synchroniser l'accès aux ressources partagés (les vases) par différents processus. C'est surtout vrai ici puisqu'on veut contrôler la quantité totale.

Le simple mot-clé synchronized au début de la méthode transfert permet de s'assurer que 2 threads n'exécuteront par simultanément la méthode. De cette manière, la quantité totale restera correcte :

import java.util.Random;

public class VasesCommuniquants {

    private static final int QUANTITE_INITIALE = 200;
    public static final int NB_THREAD_MAX = 3;
    private static int iteration = 0;

    private int[] vase = { QUANTITE_INITIALE / 2, QUANTITE_INITIALE / 2 };

    public VasesCommuniquants() {

        for (int i = 0; i < NB_THREAD_MAX; i++) {
            new ThreadTransfert().start();
        }

    }

    public static void main(String[] args) {
        new VasesCommuniquants();
    }

    public synchronized int transfert(int qte) {

        vase[0] -= qte;
        vase[1] += qte;

        iteration++;

        if (iteration % 100 == 0) {
            System.out.println("" + iteration + "itérations");
        }

        return vase[0] + vase[1];

    }

    public class ThreadTransfert extends Thread {

        Random r = new Random();
        int quantite;

        public void run() {

            while (!isInterrupted()) {

                quantite = 1 + r.nextInt(10);

                if (transfert(quantite) != QUANTITE_INITIALE) {

                    System.out
                            .println("Quantité totale invalide à l'itération "
                                    + iteration);

                    System.exit(-1);

                }

                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                }

            }

        }

    }

}


Pour ne pas synchroniser la méthode entière, tu peux aussi simplement synchroniser le bloc critique (celui qui manipule les ressources partagées) de cette manière :

import java.util.Random;

public class VasesCommuniquants {

    private static final int QUANTITE_INITIALE = 200;
    public static final int NB_THREAD_MAX = 3;
    private static int iteration = 0;

    private int[] vase = { QUANTITE_INITIALE / 2, QUANTITE_INITIALE / 2 };

    public VasesCommuniquants() {

        for (int i = 0; i < NB_THREAD_MAX; i++) {
            new ThreadTransfert().start();
        }

    }

    public static void main(String[] args) {
        new VasesCommuniquants();
    }

    public int transfert(int qte) {

        synchronized (this) {

            vase[0] -= qte;
            vase[1] += qte;

            iteration++;

            if (iteration % 100 == 0) {
                System.out.println(iteration + " itérations");
            }

        }

        return vase[0] + vase[1];

    }

    public class ThreadTransfert extends Thread {

        Random r = new Random();
        int quantite;

        public void run() {

            while (!isInterrupted()) {

                quantite = 1 + r.nextInt(10);

                if (transfert(quantite) != QUANTITE_INITIALE) {

                    System.out
                            .println("Quantité totale invalide à l'itération "
                                    + iteration);

                    System.exit(-1);

                }

                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                }

            }

        }

    }

}
0
boualiasma Messages postés 393 Date d'inscription lundi 22 juin 2009 Statut Membre Dernière intervention 23 décembre 2011 5
11 oct. 2010 à 10:59
Merci beaucoup.

- C'est quoi le type d'ordonnancement des threads crées de manière simple ?

- Quel est le type d'ordonnancement des threads crées par exemple pour le programme suivant ?

public class ThreadExtends extends Thread {
   public void run(){
      while (true) {
          System.out.println("dans ThreadExtends.run");
      }
    }
 }
    
public class Threads1{
    public static void main(String[] args) {
        ThreadExtends t0= new ThreadExtends ();
        t0.start();
         while (true) {
            System.out.println("dans thread1.main");

        }
    }
}

0
cs_jojolemariole Messages postés 519 Date d'inscription mercredi 21 mars 2007 Statut Membre Dernière intervention 19 décembre 2016 25
11 oct. 2010 à 11:27
Re,

Sympa de nous refiler les questions de ton cours...

Threads Java (intéresse-toi en particulier au paragraphe 3.3.2)
0
boualiasma Messages postés 393 Date d'inscription lundi 22 juin 2009 Statut Membre Dernière intervention 23 décembre 2011 5
11 oct. 2010 à 12:05
Merci beaucoup pour ce lien.

Quel est le programme qui permet d'implémenter l'algorithme de tri multhreadé suivant avec t représente le tableau à trier :

- Soient i et j les indices de l'intervalle de t à trier tel que i <= j.
- Si (j-i < 2) et (T[i] > t[j]), on fait l'échange entre t[i] et t[j].

- Sinon:
* Soit k=i+(j-i)/2
* On applique par un nouveau thread l'algorithme sur [i, k]
* On applique par un nouveau thread l'algorithme sur [k+1,j]
* On attend la fin des 2 threads
* On fait une fusion triée des tris des 2 threads
* On informe le thread parent que le tri sur [i, j] est terminé
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
11 oct. 2010 à 12:30
Salut,

Nan mais je rêve là .... Nous ne sommes pas là pour faire tes exo à ta place !!!

Sujet clos !





------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
0
Rejoignez-nous