Bonjour,
Je m'exerce à utiliser la librairie Jade en Java. Et j'ai rencontré un problème que j'ai résolu mais dont je ne comprend pas la provenance.
Jade est une librairie multi-agent qui permet de gérer un environnement avec des nombreux agents (ici on peut considérer que agent = thread). Dans mon cas, je veux créer
Pour cela la méthode qui créer les agents demande de lui passer un Object[]
. Cet argument pourra ensuite être récupéré par l'agent grâce à la méthode getArguments()
.
Chaque agent, une fois crée est est lancé et est initialisé par la méthode setup()
.
Mon problème est le suivant. J'ai la liste de tous le noms des agents, et je veux la passer aux agents en supprimant son propre nom de la liste. Cela peut se faire de deux façons :
- Soit avant la création de l'agent en créant une nouvelle liste qui lui sera passée en argument
- Soit dans la méthode setup en récupérant la liste de tous les noms des agents puis en supprimant son propre nom
La première méthode fonctionne sans problème. La deuxième pas du tout.
Comme Jade (et Java) sont assez verbeux, je ne vous passe qu'un extrait du code (avec la deuxième solution).
Ici le code qui permet la création de l'agent. On remarque donc que l'on passe à chaque fois a objtab la liste contenant tous les noms des agents.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | for(int i = 0 ; i< nAgents ; i ++) { agentListName.add(i, "Agent Explorer "+String.valueOf(i)); } for(int i = 0 ; i<nAgents ; i++) { c = containerList.get("container"); try { agentName=agentListName.get(i); Object[] objtab=new Object[]{agentListName}; AgentController ag=c.createNewAgent(agentName,AgentExplorer.class.getName(),objtab); agentList.add(ag); System.out.println(agentName+" launched"); } catch (StaleProxyException e) { e.printStackTrace(); } } |
Ici le code appelé pour l’initialisation de l'agent :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | protected void setup() { super.setup(); //get the parameters given into the object[] final Object[] args = getArguments(); if(args!=null){ data = (List<String>)args[0]; } else{ System.out.println("Erreur lors du tranfert des parametres"); } data.remove(this.getLocalName()); //On supprime le nom de l'agent dans la liste for(String o : data) { System.out.println("Agent :"+this.getLocalName()+"; Arg : "+o.toString()); } } |
En faisant de cette manière, j'obtiens une erreur à la compilation si il ya plusieurs agents. Cela vient du fait que l'objet data est partagé entre chaque agent. C'est comme si c'était une liste synchronisée. Chaque agent à accès à la même liste. Ce qui me parait étrange puisque clairement ce n'est pas le comportement souhaité. De toute façon la première méthode fonctionne, donc les listes sont bien censés pointées à des endroits différents en mémoire.
Donc ma question c'est comment se fait-il que le pointeur de data soit dans ce cas partagé par tous les agents au lieu d'être copié ? Le code étant un poil long vous pourrez le trouver sur le pastebin suivant (il vous faudra télécharger Jade et inclure les jar dans le projet) :
AgentExplorer.java Environement.java
Deux petites questions bonus :
- Je passe en argument un
Object[]
et pourtant ma liste se trouve dansObject[0]
pourquoi ? Eclipse de toute façon m'indique une erreur de cast. - Est-ce qu'il n'existe pas une manière plus Javanesque pour les boucles for quand elles parcourent des entiers ?
Cordialement,
Saroupille