La classe AtomicBoolean est un wrapper de boolean (une classe d'objets avec un attribut de type boolean) qui est implémenté de manière à permettre l'accès multi-thread facilement. Le second avantage est que comme c'est un objet, on peut le partager facilement entre plusieurs objets (un qui le modifira et l'autre le lira).
Pour l'implémentation de la lecture, tu devrais penser que
- si rien n'est dans le buffer, read retourne -1 (et non pas '\n'), et il ne faut surtout pas mettre ce caractère dans la saisie. Tu peux utiliser available() comme je te l'ai dit pour savoir si quelquechose (une saisie) est en attente de lecture dans le buffer. Il faut penser qu'on pourrait saisir plusieurs caractères plus vite que la boucle ne boucle, donc avoir plusieurs caractères dans le buffer.
- il serait judicieux d'utiliser un StringBuilder plutôt que de concaténer les caractères lus dans tmp (mais ce n'est pas très grave dans ton cas, seulement c'est une bonne habitude à prendre). Et tu devrais avoir un moyen de différencier le cas où la saisie est annulée avec qu'on ait pu saisir aucun caractère. Taper entrée (donc saisir une chaîne vide) est une saisie de chaîne vide, alors que si on arrête la lecture avant toute frappe tmp est aussi vide : 2 cas identiques pour 2 raisons différentes. Un boolean par exemple permettra de faire la différence.
- je t'ai dit de laisser un peu de temps dans la boucle pour les autres threads (avec un sleep() sur un temps très court). Aussi, il faut penser surtout à gérer l'interruption du thread dans cette boucle : justement, avec un sleep, tu auras une InterruptedException qui te permettra de savoir qu'il faut sortir de la boucle.
La boucle de lecture devrait être plutôt du genre
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| tant qu'il faut lire (on teste ici l'AtomicBoolean
s'il y a quelque chose à lire (test de available)
on flag qu'on a lu au moins un caractère
tant qu'il y a des octets dans le buffer (tant que read!=-1)
si le caractère lu est la touche entrée (\n) on sort des deux boucles
on concatène les caractères affichables (>=' ') correspondant dans le buffer de lecture
fin tant que
fin si
on attend (appel de sleep()) un petit peu pour laisser du temps aux autres threads de pouvoir prendre la main (et en cas d'interruption de cette attente on sort de la boucle)
fin tant que
si le flag de lecture est à true, on a lu quelque chose
donc on retourne le contenu du buffer de lecture
sinon
on retourne null
fin si |
Lorsque le thread de timeout arrive au timeout il passe l'AtomicBoolean à true et appelle interrupt sur le thread qui fait cette boucle de lecture.
[edit]j'ai oublié un truc : if (C != '\r') tmp = tmp+C; il ne faut pas prendre en compte dans tmp tous les caractères non affichable (comme par exemple \t), donc fait plutôt :
if (C>= ' ') tmp = tmp+C;
...
Partager