Bonjour,
je fais une recherche exhaustive (calcul de toutes les combinaisons possibles). Mais pour accélérer le processus, je lance plusieurs threads (autant que de CPU) et je dois donc synchroniser le travail de mes différents threads.
voici ma recherche exhaustive (classique) :
Code java : 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 private List<Integer> threadsfree = new Vector<Integer>() ; private void Compute(int column) { if ( "bas/feuille de l'arbre de recherche, donc on travaille" ) { int free = getFreeThread() ; // On attend un thread libre (appel bloquant). synchronized ( threads[free].lock ) // On synchronise le verrou. { threads[free].Work(mywork) ; // On donne le travail threads[free].lock.notify() ; // On lance le thread. } return ; } ... }
Pour faire cela, j'ai donc une méthode qui s'occupe d'attendre qu'un thread soit libre :
Code java : 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 private synchronized int getFreeThread() { while ( threadsfree.isEmpty() ) // On attend qu'un thread soit libre. try { wait() ; } catch ( InterruptedException e ) { e.printStackTrace() ; } int free ; synchronized ( threadsfree ) { free = threadsfree.get(0) ; // On récupère le numéro du thread libre threadsfree.remove(0) ; // On supprime le thread de la liste. } // J'ai testé, ici le thread "free" n'est plus dans la liste et il n'y a pas de doublon. return free ; }
Et voici le thread qui fait le travail demandé :
Code java : 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 private class SysResThread extends Thread { private int number = -1 ; public Object lock = new Object() ; public SysResThread(SystematicResearch parent, int number) { super() ; this.parent = parent ; this.number = number ; // Numéro unique (bien évidemment). } public void run() { while ( true ) // On boucle pour garder le thread actif. { synchronized ( lock ) { try { parent.addFreeThread(number) ; // On a finit (ou pas commencé), donc on signale que l'on est libre. lock.wait() ; // On attend du boulot. Seul le parent libère le thread. // On arrive ici que si le thread a été libre et a été libéré par la classe mère/parent. // Souci... le thread est toujours dans la liste des threads libres :-( } catch ( InterruptedException e ) { e.printStackTrace() ; } } // ... on fait la travail ici. } } }
Mais tout ceci ne fonctionne pas :-(
Dans la classe/thread, je m'aperçois qu'après que le thread ait été libéré par la classe parent, il apparaît toujours dans la liste des threads libres :-(
Il me semble avoir tout synchronisé comme il se doit, attendre les threads, etc.
Mais pourquoi diable est ce que parfois un thread apparaît toujours dans la liste des threads libres ?
Est ce que quelqu'un aurait une idée ?
Merci par avance...
Partager