IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

La bonne méthode pour faire des timers


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de Tigrounette
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    132
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 132
    Par défaut La bonne méthode pour faire des timers
    Bonjour à tous, je vous explique mon problème :

    J'ai un petit jeu multijoueur dans lequel les joueurs peuvent poser des bombes qui explosent au bout d'un certain temps (Un bomberman). Le moment ou les bombes explosent sont donc gérés par le serveur (qui est en java).

    Le problème, c'est quand il y a trop de monde, donc quand plusieurs centaines de joueurs posent leurs bombes en même temps, le serveur commence à m'envoyer cette erreur : java.lang.OutOfMemoryError: unable to create new native thread, pour finir par ne plus réagir. Le reste des informations d'indique que c'est en voulant ajouter une nouvelle bombe qu'il plante.

    Pour créer une bombe côté serveur, j'utilise cette classe (j'ai simplifié un peu pour garder l'essentiel) :

    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
    public class Bombe extends Thread {
    	private int Temps;
    	private boolean Active = true;
     
    	private Bombe(int TEMPS) {
    		Temps = TEMPS;
    		start();
    	}
     
    	public void run() {
    		try {
    			sleep(Temps);
    			if (Active) {
    				Explosion();
    			}
    		} catch (Exception e) {
    		}
    	}
    }
    Mais apparement c'est une mauvaise méthode

    J'aimerais donc connaitre la bonne méthode pour retarder l'execution d'une fonction d'un certain temps. L'objectif étant de pourvoir en faire plusieurs centaines simultanément ^^

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,



    Si tu génères un grand nombre de thread au même moment ce problème est tout à fait normal. Les threads sont des ressources systèmes critiques et il ne faut pas en abuser.

    Dans ton cas la meilleur solution serait de passer par un thread unique qui gèrerait toutes les explosions. Cela peut se faire tout simplement en utilisant la classe Timer et sa méthode shedule() pour planifier un événement à un instant donné...


    a++

  3. #3
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 897
    Billets dans le blog
    54
    Par défaut
    Dans leur présentation de JavaOne 2008, Gfx et Chet se sont justement penchés sur le problème de multiples Timer (dans leur cas dans une GUI Swing et donc avec le Timer Swing plutôt que celui de java.util). Ils indiquent bien qu'avoir trop de Timer est un gène car alors cela pompe trop de ressources et on obtient l'effet inverse de celui recherché.

    Leur solution consiste donc en un Timer unique à faible résolution et des évènements qui sont stockés dans un arbre/graphe. Si je ne m'abuse (et si je n'ai pas tout mélangé ) s'est plus ou moins inspiré/dérivé de GraphScene pour JavaFX (à moins que ce ne soit l'inverse). Bref, il est possible que tu doives t'inspirer d'une telle solution (leur présentation est disponible en session audio sur le site de JavaOne ou en PDF sur le site de Gfx - http://www.curious-creature.org/2008...-javaone-2008/). Bien sur il faudra t'arranger pour que les événements lancés par le Timer s'exécutent de manière asynchrone histoire de ne pas ralentir le Timer lui-même.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  4. #4
    Membre confirmé Avatar de Tigrounette
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    132
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 132
    Par défaut
    Bon, après quelques test je reviens vers vous.

    j'ai utilisé la méthode de bouye. J'ai une boucle dans un thread à part qui vérifie toutes les 50 millisecondes si une bombe doit exploser ou non (si c'est bien cette méthode).

    Alors ça va un peu mieux, mais le serveur plante vers 300 peronnes au lieu de 200, donc c'est pas encore trop ça.

    Bref, a part le thread de chaque client, j'en ai pas de masse non plus. 2 thread par partie pour gérer le chronomètre et parfois quelques autres pour gérer différentes choses.

    En gros, le serveur dois planter quand environ 500-600 thread sont actif en même temps et refuse d'en créer d'autre avec toujours le même message d'erreur : java.lang.OutOfMemoryError: unable to create new native thread.

    Le problème, c'est que je regarde un peu ce qui se passe niveau mémoire à ce moment là et je me rend compte que le programme java m'indique qu'il utilise environ 60 mo pour 508 mo de libre

    C'est un peu énervant comme bug, j'ai tenté de me renseigner sur cette erreur mais j'ai pas trouvé grand chose. Ya t'il une manipulation à faire pour autoriser une application java à créer autant de thread qu'elle veut ? Au niveau de la compilation ou du système d'exploitation ?

  5. #5
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 897
    Billets dans le blog
    54
    Par défaut
    Quelle JVM ? Quel OS ? Quel vendeur ? As-tu utilise un flag -Xmx<kekchose> particulier pour augmenter la taille de la memoire utilisable ?

    De toute maniere tu seras toujours limite, y compris par l'OS : on ne peut pas creer une infinite de Thread. Pour des tres grosses quantites tu devras utiliser des Thread pools et faire du scheduling.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  6. #6
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    salut,

    Bref, a part le thread de chaque client
    Pour ce point précis, j'imagine que tu parles du serveur et donc du thread rattaché à la socket client pour faire le 'read()' bloquant.

    Au lieu de faire un thread par socket client, tu peux utiliser l'API Java NIO pour n'avoir qu'un seul thread pour toutes les socket clientes.

    En gros, le principe de l'API NIO est d'avoir un seul appel bloquant sur un 'selector' qui sera débloqué dès qu'une socket parmi toutes celles enregistrées dans le 'selector' aura reçu quelque chose (ou se sera déconnectée).

    Le moment ou les bombes explosent sont donc gérés par le serveur
    Peut-être que pour ça tu peux utiliser une approche différente (idée saugrenue, mais bon): que ce soit un des joueurs de la partie (celui à qui l'explosion profite le moins) qui prévienne lorsqu'une bombe a explosé en envoyant le message au serveur. Le serveur n'aura alors plus qu'à vérifier que le client dit vrai et qu'à ce moment là la bombe aurait bien du exploser, et faire le traitement en conséquence a postériori.

  7. #7
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Tigrounette Voir le message
    Bref, a part le thread de chaque client, j'en ai pas de masse non plus. 2 thread par partie pour gérer le chronomètre et parfois quelques autres pour gérer différentes choses.

    En gros, le serveur dois planter quand environ 500-600 thread sont actif en même temps et refuse d'en créer d'autre avec toujours le même message d'erreur : java.lang.OutOfMemoryError: unable to create new native thread.

    Le problème, c'est que je regarde un peu ce qui se passe niveau mémoire à ce moment là et je me rend compte que le programme java m'indique qu'il utilise environ 60 mo pour 508 mo de libre
    Ce n'est pas un problème de mémoire, mais tout simplement l'impossibilité de créer de nouveau thread...

    D'après ce que tu dis (300 joueurs, 500-600 threads), on dirait que tu arrives à utiliser 2 threads/joueurs. C'est peut-être un peu beaucoup.

    Les systèmes d'exploitations ont des limites au nombre de thread par processus, et tu dois atteindre ces limites.

    Si tu utilises seulement des threads pour les données clientes, NIO pourrait en effet être la solution...

    a++

  8. #8
    Membre confirmé Avatar de Tigrounette
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    132
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 132
    Par défaut
    Je commence à comprendre tous ça un peu mieux. Pour moi, faire des thread dans tous les sens était une bonne manière de faire C'est vrai qu'en y réfléchissant, je pourrais utiliser 3-4 thread pour gérer tous ce qui n'est pas thread client et tenter d'utiliser java.nio pour les clients.

    Je suis en train de tout casser pour utiliser java.nio, je vous tiens au courant

Discussions similaires

  1. [WD20] Le choix de la bonne méthode pour filtrer des données
    Par lololebricoleur dans le forum WinDev
    Réponses: 3
    Dernier message: 20/02/2015, 21h04
  2. Bonne méthode pour faire un formulaire ?
    Par tiesto95 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 15/03/2009, 18h16
  3. une bonne librairie pour faire des log ?
    Par lezurp dans le forum C++
    Réponses: 12
    Dernier message: 02/03/2009, 14h10
  4. Réponses: 5
    Dernier message: 23/04/2008, 15h41
  5. Meilleure méthode pour faire des coins arrondis
    Par kodokan dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 17/09/2006, 15h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo