Partage
  • Partager sur Facebook
  • Partager sur Twitter

Synchronisation getter & setter / ArrayList

Synchronized / ArrayList / Multi-Threading / ConcurrentModification

    16 février 2020 à 0:27:00

    Bonsoir/Bonjour, j'espère que tout se passe bien de votre côté ;-)

    Du miens, je me heurte à un mur. Le contexte : jeu vidéo avec une grosse ArrayList d'entitées, qui est modifiée (update, ajout et suppression d'entitées) dans un thread "Brain" et qui est lue par un autre thread "Panel" (les deux threads étant asynchrones) afin d'afficher toutes les entitées. Contexte peu exotique ^^

    Le problème, vous l'avez compris, est de ne plus avoir de ConcurrentModificationException. La solution passe par l'utilisation du mot clé synchronized. Cependant, mettre ce mot clé sur le getter et le setter de mon ArrayList d'entitées ne fonctionne pas.

    J'ai résumé la situation dans ces quelques lignes :

    On a 2 thread et une arrayList : un créateur de banane, qui rajoute des bananes dans l'ArrayList et un compteur de banane qui regarde ce qu'il y a dans l'arrayList. J'ai mis les synchronized pour faire joli mais je sais bien qu'ils ne sont pas utiles ainsi.

    package testSynchronized;
    import java.util.ArrayList;
    public class Main { public static void main(String[] args) { new BananaManager(); } } class Banane {} class BananaManager { public ArrayList<Banane> bananes = new ArrayList<Banane>(); public BananaManager() { new Thread(new FabricateurDeBananes(this)).start(); new Thread(new CompteurDeBananes(this)).start(); } public synchronized void addBanane() {bananes.add(new Banane());} // comme le getter et le setter ne sont pas sous public synchronized ArrayList<Banane> getBananes() {return bananes;} // le même synchronized, il y a la concurrentexception } class FabricateurDeBananes implements Runnable { BananaManager bm; public FabricateurDeBananes(BananaManager bm) {this.bm = bm;} @Override public void run() {while (true) {bm.addBanane();}} } class CompteurDeBananes implements Runnable { BananaManager bm; public CompteurDeBananes(BananaManager bm) {this.bm = bm;} @Override public void run() { while (true) {for (Banane banane : bm.getBananes()) {System.out.println("Je viens de compter une banane");}} } }

    Je me suis renseigné sur l'utilisation de synchronized ; mais je ne vois pas comment, au sein d'un seul bloc, je peux joindre un getter et un setter. J'ai également explorer la voie des attributs volatiles, en vain...

    Je vous remercie pour votre aide précieuse, et je vous souhaite une bonne soirée/journée ;-)

    -
    Edité par JeanDujardin28 16 février 2020 à 0:29:20

    • Partager sur Facebook
    • Partager sur Twitter
      16 février 2020 à 7:50:16

      Bonjour,

      Regarde plutôt ce qui existe déjà. Par exemple, la méthode Collections.synchronizeedList

      https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedList(java.util.List)

      • Partager sur Facebook
      • Partager sur Twitter
        16 février 2020 à 11:25:13

        brubru777, merci énormément. Je ne connaissais absolument pas ce type de List. C'est très puissant !
        • Partager sur Facebook
        • Partager sur Twitter
          17 février 2020 à 13:19:56

          Tu peux aussi utiliser la classe Vector.

          C'est une ancienne classe (un dinosaure du Java), peu utilisée, mais elle conserve l'intérêt d'être justement une List synchronisée.

          • Partager sur Facebook
          • Partager sur Twitter

          Synchronisation getter & setter / ArrayList

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown