Salut salut,
bon je viens quérir des idées nouvelles sur un problème qui m'hérisse le poil depuis le week end dernier. Les plus habiles auront deviné qu'il s'agit de Thread ...
Alors, je dois réaliser une appli qui compte le nombre de nombre premier jusqu'à une certaine limite. Je dois le faire de façon séquentielle puis multi-tâche pour comparer les résultats. Dans la compréhension comme dans le concert, rien de bien difficile.
Pour la version séquentielle, rien de bien compliqué. Je pensais de même pour la version avec thread, sauf que je me heurte à un problème. Avant tout, voici un aperçu de ma structure :
Voila pour mon code, à quelques omissions près, j'ai limité le code à ce que me semble nécessaire. Le problème est que ma méthode avec thread est plus longue à l'exécution que la méthode séquentielle, ça se joue à une ou plusieurs dizaines de ms.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84 public class client extends Thread { // limite haute et limite basse comprises dans l'intervalle int min; int max; client(int _min, int _max) { this.min = _min; this.max = _max; this.start(); } public void run() { for (int i=this.min; i <=this.max; i++) { if (EstPremier(i)) { server.EstPremier(); } } } public boolean EstPremier(int _test) { // retourne true si premier, false sinon. ... } } public class server { static int nbPremiers = 0; static int limiteHaute; static int nbClients; public static void main(String[] args) throws InterruptedException, IOException { limiteHaute = Integer.decode(args[0]); System.out.println("---start---"); long start = getTimeStamp(); if (Integer.valueOf(args[1]) == 1) { //sequentiel(); } else { nbClients = Integer.decode(args[2]); int interval = limiteHaute/nbClients; int min = 0; int max = 2; for (int i=0; i<nbClients; i++) { min = max; max = min+interval; if (max > limiteHaute) { max = limiteHaute; } new client(min, max).join(); } } long stop = getTimeStamp(); System.out.println("---stop---"); System.out.println((nbPremiers)+" nb premiers en "+(stop-start)+" ms"); } public static void EstPremier() { nbPremiers++; } public static long getTimeStamp() { return new Date().getTime(); } }
J'ai fait mes tests sur un server de calcul de fac ayant un doute à la vue de mes résultats sur ma machine perso. J'ai ensuite essayé une version avec la classe client qui implémentait Runnable (avec les modifications nécessaires) : pareil. En dernier lieu, j'ai viré la partie de génération automatique des plages de nombres, en ne laissant que 2 plages écrites à la main, en utilisant l'interface Runnable.
Cette fois ci, malgré les isAlive pour remplacer les join(), le programme ne va pas jusqu'au bout. C'est à dire qu'il s'arrête avant d'avoir tout calculé car je n'ai pas le bon nombre de nbPremiers.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 public class client implements Runnable { ... client(int _min, int _max) { this.min = _min; this.max = _max; //this.start(); } ... } public class server { ... public static void main(String[] args) throws InterruptedException, IOException { ... client c1 = new client(2, limiteHaute/2); client c2 = new client((limiteHaute/2)+1, limiteHaute); Thread t1 = new Thread(c1); Thread t2 = new Thread(c2); t1.start(); t2.start(); while (t1.isAlive() || t2.isAlive()) { sleep(100); } ... } ... }
En résumé, quand j'utilise les join(), j'ai l'impression, en debugant un peu avec des println, qu'il lance les clients les uns après les autres, en attendant que le précédant est fini, séquentiellement quoi. Et quand j'utilise les isAlive, les thread ne vont pas au bout de leur travail.
Je suis dorénavant à court d'idées.
Merci d'avance.
Partager