Le problème était que lorsqu'un élément est écrit dans le PipedWriter, il n'indique pas automatiquement à PipedReader qu'il y a des données à lire. Lorsque vous essayez de lire PipedReader et que le tampon est vide, PipedReader boucle et attend en utilisant un appel wait(1000)
jusqu'à ce que le tampon ait des données.
La solution est d'appeler PipedWriter.flush()
toujours après avoir écrit quelque chose sur le tuyau. Tout ce que la chasse d'eau est appelez notifyAll()
sur le lecteur. La correction du code en question looks like this.
(Pour moi, l'implémentation de PipedReader/PipedWriter ressemble beaucoup à une optimisation prématurée - pourquoi ne pas notifierAll sur chaque écriture? Aussi les lecteurs attendent dans une boucle active, se réveillant chaque seconde, au lieu de se réveiller Le code contient aussi quelques commentaires, que la détection de thread de lecteur/graveur n'est pas assez sophistiquée.)
Ce même problème semble être également dans PipedOutputStream. Dans mon projet actuel appelant flush()
manuellement n'est pas possible (ne peut pas modifier IOUtils.copy() Commons IO's), donc je l'ai corrigé en créant low-latency wrappers pour les classes de tuyau. Ils fonctionnent beaucoup mieux que les classes originales. :-)
Cela peut ne pas être ce que vous voulez, mais votre thread d'écriture pourrait-il notifier le fil de lecture après avoir écrit quelque chose? Et le fil de lecture continuera à lire pendant que 'ready()' est vrai, puis dormira quand ce n'est pas le cas? – Phil
Pourriez-vous nous indiquer votre code, s'il vous plaît?Le 'wait (1000)' ne devrait pas être le problème, parce que l'auteur notifie le lecteur quand quelque chose est écrit. Le lecteur s'échappe alors de son attente(). – tangens
Merci, Phil. Je ne suis pas à la maison maintenant, donc je ne peux pas le tester, mais basé sur le code source PipedWriter.flush() apparaît pour informer les lecteurs. Je vais essayer plus tard aujourd'hui. –