OVH Cloud OVH Cloud

Question d'implementation

14 réponses
Avatar
julien
Bonjour
Je vais essayer de faire un petit casse-brique. Pour l'insatnat, je me
content d'afficher plusieurs balles qui rebondissent sur 4 murs. Mais
j'éhsite sur la façon de l'implémenter:

1/ faire un thread pour chaque balle. A l'intèrieur de chaque thread,
prévoir une fonction qui déssine la balle à l'écran.
Problèmes:
- dessiner une balle va effacer toutes les autres je pense.
- comment partager le même "graphics" entre les thread? D'habitude, sans
thread, je surcharge la méthode paint(Graphics g). Mais comment faire
dans chque thread?

2/ faire un thread pour chaque balle + un thread (ou timer?) pour
dessiner chaque ball. paint(Graphics g) ressemblera à ça:
ball1.draw(g);
ball2.draw(g);
ball3.draw(g);
...

ou bien utiliser des variables de chque thread:
g.draw(ball1.x, ball1.y, ...);
g.draw(ball2.x, ball2.y, ...);
g.draw(ball3.x, ball3.y, ...);
...

-est-ce posssible: puis-je un appel externe à une fonction d'un thread
quand celui-ci est en exécution?

La méthode 2 me semble la plus simple.

Un avis/conseil?

Merci
Julien

4 réponses

1 2
Avatar
kpdpbis
julien wrote in message news:<418c6462$0$30957$...
Juste par curiosité, quels sont les commentaires qui te suprennent .... ?


De Laurent Bossavit: un seul thread serait mieux
->gérer le balles, puis les briques, + d'autres objet avec un seul
thread, ça me parait plus compliqués que de faire des threads "indépendants"

De kpdp: c'est "naif" de faire un thread par objet
->bon, ça va peut-être dans le sens du message au-dessus

utiliser un FIFO
->je vois pas trop pourquoi: l'affichage devra se faire en une seule
fois en fonction des coordonnées/états des différents objets à l'instant t

Parce que la balle est un objet métier. Ce n'est pas à elle de savoir se
dessiner
->faut que je vois ce que veut dire "objet métier"
->je pense qu'il est plus facile de demander à chaque objet de se
dessiner. Il devrait avoir intrasèquement toutes les données pour se
dessiner lui-même.

Certaines personnes sont pour 2 seul thread unique, kdpd au contraire
pour multiplier le nombre de threads.

Julien


Bonjour,

Je m'explique :
Si tu avais 10000 objets à afficher, est ce que tu ferais 10000
threads ? C'est pour cela qu'implicitement tu peux te rendre compte
qu'un thread par objet n'est probablement pas la bonne façon de faire.
Avec 4 objets, cela fonctionne mais c'est "naif".

Au delà de ça, on peut se poser la question de savoir quand il est
pertinent de créer des threads. En fait je te conseille de voir un
thread comme un traitement asynchrone par rapport au reste du
programme. Typiquement le rafraichissement graphique est dans un autre
référentiel de temps que le calcul des points. En effet, si tu
aggrandis ta fenêtre, tu t'attends à avoir un rafraichissement
immédiat ( et pas aprés le calcul des nouvelles coordonnées )

Donc pour moi le calcul de toutes les coordonnées doit se passer dans
le même thread. Ce Thread travaille sur un liste de 4 points. Si tu as
10000 points, il travaillera sur un liste de 10000 points. 10000 objet
dans une liste cela reste acceptable ( contrairement à 10000 threads )

Néanmoins le calcul des points en multithread peut s'expliquer :
Imagine que tu ais des capteurs placés sur tes balles, ces capteurs
emettent des signaux quand les balles se déplacent. Dans ce cas chaque
balle est bien gérés dans un thread séparés. Le déplacement de la
balle se fait à l'initiative de la balle ( et pas du programme ). Donc
un mouvement de la balle se gère exactement comme un évènement
utilisateur ( c'est à dire avec un thread dédié qui passe la majorité
de son temps à attendre les nouveaux évènements ). C'est pour cela que
la conception en multithread peut être taxée de "naive" mais ce n'est
pas une erreur de conception.

La gestion d'évènement en multithread ( si le calcul des coordonnées
se fait en multithread) induit logiquement l'utilisation de la FIFO.
C'est beaucoup plus simple de créer un pile d'évènement que l'on
dépile en monothread, que de gérer les update de ton model en
multithread sans créer de deadlock. Du coup il n'y a aucun
"synchronized" sur le model. D'expérience je n'ai jamais vu
fonctionner une application qui gère "à la main" des synchronisation
sur le model : "Alors si je fais ça je synchronize tel obet et tel
objet mais lui même synchronize cela alors du coup cela revient à
faire....". Au final, cela ne marche jamais ( sauf dans le cas
d'application triviale ) et le pire, c'est que c'est indébuggable.

La balle est effectivement un objet métier. C'est a dire un objet qui
a un sens fonctionnel, si tu devais persister ton application, les
coordonnées des balles seraient probablement la seule information que
tu stockerais en base. De plus, une balle a un UNIQUE jeu de
coordonnées à un instant données. Par contre la balle peut posséder de
multiples représentations graphiques...Tu peux dessiner les
trajectoires, afficher les coordonnées dans une JTable, ect...Donc si
tu mets la représentation graphique dans l'objet tu vas te retrouver
avec un objet monstreux dans lequel tout le monde va faire des
modifications. Il est préférable de séparer les responsabilité d'un
coté la balle et ses coordonnées, d'un autre X objets graphique qui
utilisent l'objet métier pour définir une représentation graphique
possible.

D'ou vient le mot "métier" ? Le but de ton programme est de gérer les
déplacements de balle. Tu peux tres bien concevoir que le rendu
graphique soit délégué à des développeurs qui n'ont pas besoin de
savoir comment se déplace les balles. D'ou l'importance de séparer la
logique métier des représentations graphiques car les développeurs qui
gérent les déplacement de la balle doivent connaitre la physique +
l'informatique : Ils sont plus rares et ne s'intéressent peut être pas
aux IHM. Comme tu peux le voir, La logique d'une bonne modélisation
"Objet" traduit aussi une certaine logique "humaine" d'organisation
des équipes.

J'espère que tu es moins perplexe aprés cette réponse ;-)

Kpdp


Avatar
julien
kpdp wrote:
Bonjour,

Je m'explique :
Si tu avais 10000 objets à afficher, est ce que tu ferais 10000
threads ? C'est pour cela qu'implicitement tu peux te rendre compte
qu'un thread par objet n'est probablement pas la bonne façon de faire.
Avec 4 objets, cela fonctionne mais c'est "naif".
[...]


Voilà ce que j'ai fait:
* Je pars avec 3 types d'objets: un curseur, des balles, et des briques
* le curseurs et les balles doivent se déplacer, on plusieurs états
(taille, couleur, ...)
* une brique a une position fixe et 2 états (visible ou invisible)

Pour l'instant, je n'ai fait que les balises, de la façon suivante:
* la classe principale affiche le canavs et donne la methode paint()
* 1 balle = 1 thread avec le cycle:
- 1 balle change de taille et de position
- 1 balle sleep un certains temps
- la balle appelle la methode paint() de la classe principale.
Cette methode paint() appelle la methode draw() de chque thread

L'incovenient majeur, c'est qu'il y a de nombreux appels à la méthode
paint(). L'avantage, c'est que l'affichage se fait uniquement quand il
est requis: s'il n'y a pas de balle afichée, paint() n'est pas appelé.


Quelles sont les avantages ou inconvénients des autres implémentations?

Julien

Avatar
kpdpbis
Quelles sont les avantages ou inconvénients des autres implémentations?

Julien


Je ne sais pas si tu as lu en entier mes posts précédents mais je te
répète que tu mélanges dans le même objet :

Les données : Les coordonnées des balles
Le traitements : Le calcul des coordonnées
La vue : Le rendu graphique des balles
L'environnement de lancement : La gestion des threads

Il y a des milliers d'autres implémentations possibles donc il n'est
pas possible de te lister des avantages et des inconviénents. Ta
conception revient à dire : J'ai un objet qui fait tout. C'est
toujours possible sur un exemple trivial.

Avatar
Laurent Bossavit
Julien,

->gérer le balles, puis les briques, + d'autres objet avec un seul
thread, ça me parait plus compliqués que de faire des threads "indépendants"


Compliqué de quelle façon ?

Evite de te "verrouiller" dans une conception. Programme une version
avec N threads, une version avec 1 seul, et observe la différence. Comme
ça tu n'auras pas à départager les avis des gens du newsgroup. Les
conseilleurs ne sont pas les payeurs... :)

Laurent

1 2