En fonctionnant comme ça c'est mieux, quand même, oui. Pas nécessaire de consommer du CPU pour rien.
Ce que tu ne comprends pas, c'est qu'avec la variable état volatile, le thread s'arrête bel et bien. Juste un peu plus tard que le moment où tu regardes s'il est arrêté.
Pourquoi pas, mais vérifier l'état du thread n'est pas intéressant. Qu'est-ce que ça peut faire s'il n'est pas encore fini ? Il a mis la variable fini à true, donc il a terminé son boulot.
Tu peux pas être réactif en vérifiant une condition qui changera n'importe quand. Pour réagir quand le thread termine complètement, il faut attendre sa fin avec join()... Mais on attend pas la fin d'un thread dans l'EDT ! Tu pourrais avoir un autre thread qui attend la fin du premier mais c'est l'œuf qui se mord la queue.
Le mieux étant donc de réagir quand le thread annonce qu'il a fini son boulot, avec son appel à un observateur, sans se soucier de savoir s'il est vraiment terminé.
En ce qui me concerne, je continue de penser que tu devrais créer un seul thread qui dure aussi longtemps que ton appli, et lui envoyer du travail chaque fois que tu as du travail à faire. Après tout, créer plusieurs threads, c'est si tu veux leur permettre de travailler en même temps. Et là c'est pas le cas, un thread doit pas commencer avant que le précédent se termine... Donc en fait il faut un seul thread.
J'ai créé un jeu de mémorisation des chants d'oiseau. Il fonctionne parfaitement sous Windows et sous Mac. Un chant se fait entendre, il y a 10 propositions de nom et on doit retrouver le bon par mis ces 10. En plus il y a une gallerie d'oiseaux qui permet d'écouter le chant d'un oiseau choisi et une sonothèque qui permet d'écouter les chants les uns après les autres.
J'ai voulu utiliser getResourceAsStream pour empaqueter toutes mes ressources dans le jar et démarrer le jeu par le clic sur celui-ci quel que soit l'OS. Avant j'utilisais un ZIP que l'utilisateur devait décompresser avant de pouvoir lancer le programme en cliquant sur le jar. les ressources étaient dans des répertoires à côté du jar.
Comme indiquer précédemment il y a parfois un bug mais il n'est pas bloquant.
Mon problème est donc de lancer la lecture d'un fichier son (à un endroit quelconque du fichier), de pouvoir le mettre en pause, d'arrêter la lecture, et à la fin de la lecture mettre en pause ou reprendre au début.
C'était effectivement la solution.
Voici le code
La classe Essai
Et le code du fil
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
85
86
87
88
89
90
91
92
93
94 public class Essai extends JFrame implements ActionListener, ObservateurFil { private Fil monThread; private JButton stop = new JButton("Stop"); private JButton pause = new JButton("Pause"); private JButton play = new JButton("Play"); private boolean boucle = true; private boolean fini = false; public Essai () { super("test Thread"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); monThread = new Fil(); monThread.ajouteObservateur(this); monThread.start(); monThread.setDebut(2); JPanel boutons = new JPanel(); boutons.setLayout(new FlowLayout()); play.setEnabled(true); pause.setEnabled(false); stop.setEnabled(false); play.addActionListener(this); pause.addActionListener(this); stop.addActionListener(this); boutons.add(play); boutons.add(pause); boutons.add(stop); this.add(boutons,BorderLayout.SOUTH); pack(); setLocationRelativeTo(null); setVisible(true); } @Override public void actionPerformed(ActionEvent e) { System.out.println(Thread.currentThread()); if (e.getSource() == stop) stop(); else if (e.getSource() == play) play(); else if (e.getSource() == pause) pause(); } private void pause() { stop.setEnabled(true); play.setEnabled(true); pause.setEnabled(false); monThread.setEtat(EtatFil.PAUSE); } private void play() { if (fini) { monThread.setDebut(0); fini = false; } stop.setEnabled(true); pause.setEnabled(true); play.setEnabled(false); monThread.setEtat(EtatFil.PLAY); } private void stop() { fini = true; stop.setEnabled(false); pause.setEnabled(false); play.setEnabled(true); monThread.setEtat(EtatFil.STOP); } @Override public void finThread() { fini = true; if (boucle) play(); else stop(); } public static void main(String ...args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { new Essai(); } }); } }
Donc on démarre avec debut à 2, le défilement fonctionne très bien, pause permet d'arrêter temporairement le défilement et de reprendre là où on était arrivé, stop arrête le défilement on reprend la lecture à 0, lorsque début arrive à 5 cela s'arrête et si boucle est à true on reprend avec debut = 0.
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 public class Fil extends Thread { private volatile EtatFil etat; private ObservateurFil observateur; private volatile int debut = -1; public Fil() { super("Test Thread"); etat = EtatFil.STOP; } public void ajouteObservateur(ObservateurFil of) { this.observateur = of; } public void setDebut(int x) { debut = x; } public void run() { while(true) { if(etat == EtatFil.PLAY) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } debut++; if (debut > 4) observateur.finThread(); else System.out.println(debut); } } } public void setEtat(EtatFil e) { etat = e; } }
Mis à part le fait que ça marche, est-ce que cette construction est correcte ?
Est-ce utile de déclarer les deux variables etat et debut comme volatile ?
Ce qui est mal géré c'est le skip qui permet de lancer la lecture à un endroit aléatoire.
Pour ce qui est du bug, une fois que j'aurai mieux compris le fonctionnement que je veux faire je reviendrai vers vous. Je considère le problème ayant initié ce fil de discussion comme résolu.
Merci à tous de vos conseils et de vous être penché sur le problème.
Pour ceux que l'idée intéresse le programme dans une version antérieure est ici :
https://drive.google.com/file/d/0B81...it?usp=sharing.
Partager