Bonjour,
Je rencontre un problème de ConcurrentModificationException dans le cas ci dessous.
J'ai peut être trouvé une solution et je voudrais votre avis : est elle correcte ? y a t'il plus propre ?
Ajout d'un Listener :
Notification des listeners :
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 public boolean addUpdateListener ( UpdateListener p_listener ) { ... if (!this.m_listeners.contains( p_listener )) { listenerAdded = this.m_listeners.add( p_listener ); } else { ... listenerAdded = false; } ... }
Avec cette configuration, une exception de type ConcurrentModificationException est levée, de manière non systématique lors de la phase d'ajout des listeners.
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 public void start ( ) { this.m_timer.scheduleAtFixedRate( new TimerTask( ) { public void run ( ) { ... notifyUpdate( ); } } , 0 , UPDATE_RATE); } private void notifyUpdate ( ) { for (UpdateListener listener : this.m_listeners) { listener.clientUpdated( ); } }
Cette exception pointe la boucle for de la méthode notifyUpdate.
Solution testée:
Résultat :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 private void notifyUpdate ( ) { for (UpdateListener listener : new ArrayList<UpdateListener>(this.m_listeners)) { listener.clientUpdated( ); } }
Je n'ai plus constaté d'exception.
Problème 1 :
Comme la méthode addUpdateListener est suceptible d'être appellée depuis un thread différent, je ne sais pas si il faut aussi faire attention à la synchronization (Collections.synchronizedList(), utilisation d'Iterator ...)
Problème 2 :
Etant donné que mon UPDATE_RATE est petit (20 ms), y a t'il un moyen moins couteux que de recréer une copie de la liste à chaque cycle ?
Problème 3 :
Est-ce que je ne devrais pas travailler du côté du AddListener plutôt que du côté de la méthode notifyUpdate ?
Certe l'exception pointe vers cette méthode, mais j'ai lu que l'exception était dûe à la modification d'un liste alors qu'elle est en cours d'utilisation (de parcours?) et c'est plutôt dans le addListener que se produit la modification ...
Merci pour vos remarques et vos propositions
Partager