8
votes

Meilleure alternative pour Pipedreader / VoipeDwriter?

J'ai besoin d'avoir un flux de char tampon dans lequel j'écris dans un fil et à partir de laquelle j'ai lu un autre fil. en ce moment J'utilise PipeDreader et Voipewriter pour cela , mais ces classes provoquent un problème de performance: PIPEDREADER fait un attendre (1000) lorsque son tampon interne est vide, ce qui provoque une traînée de mon application visiblement.

Y aurait-il une bibliothèque qui fait la même chose que Pipedreader / PipedWriter, mais avec de meilleures performances? Ou devrai-je mettre en œuvre mes propres roues?


3 commentaires

Cela peut ne pas être ce que vous voulez, mais votre fil d'écriture serait-il capable de notifier le fil de lecture après avoir écrit quelque chose? Et le fil de lecture continuera à lire tandis que prêt () est vrai, puis dormez quand ce n'est pas?


Pourriez-vous nous montrer votre code, s'il vous plaît? Le attendre (1000) ne devrait pas être le problème, car l'écrivain notifie le lecteur lorsque quelque chose est écrit. Le lecteur s'échappe alors de son attente ().


Merci, Phil. Je ne suis pas maintenant à la maison, je ne peux donc pas le tester, mais sur la base du code source Pipedwriter.flush () semble informer les lecteurs. Je vais essayer plus tard aujourd'hui.


4 Réponses :


1
votes

Il devrait être assez facile d'envelopper une API de flux de charme autour de blockingQueue .

Je dois dire, cependant, il semble assez pervers que pipedrader utiliserait des interrogations pour attendre les données. Est-ce documenté quelque part ou l'avez-vous découvert pour vous-même en quelque sorte?


5 commentaires

Je pense que vous vouliez dire sur " Java. Sun.com/javase/6/docs/api/java/util/concurrent/... "


Oui, c'est mon plan B, si je ne trouve pas de classe qui fait déjà ce dont j'ai besoin.


Merci Phil. J'étais trop rapide sur le tirage au sort avec ma recherche Google. :-)


En effet c'est assez pervers. J'ai découvert le décalage dans mes tests, profilé la cause d'être dans PipedReader et j'ai trouvé la raison d'être l'attente du code d'attente (1000) d'appels à Java2s.com/open-source/java-document/6.0-java-core/IO- Nio / JAV A / ... - Ce n'est pas la première fois que certaines des bibliothèques standard de Java (depuis JDK1.1) sont codées de manière modifiée.


Juste pour clarifier aux lecteurs: attendre (1000) n'est pas comme SLEEP (1000) - il tombe immédiatement lorsqu'il est notifier ed ces données est disponible. Le délai d'attente est de gérer les situations d'erreur - si le fil source de données meurt de manière inattendue et ne peut plus en informer, en particulier.



0
votes

J'ai mis en place quelque chose d'un peu similaire, et a posé une question si quelqu'un d'autre avait mieux Code pensé et testé.


0 commentaires

1
votes

@esko Luontola, j'ai lu votre code dans le paquet SBT pour essayer de comprendre ce que vous faites. Il semble que vous souhaitiez démarrer un processus processus et transmettre l'apport à celui-ci et que le résultat de l'action soit tied à différents endroits. Est-ce que c'est du tout correct?

J'essaierais de modifier la boucle principale dans ReaderAtowriTercoPicier de sorte que, au lieu de faire un lue () - une opération de blocage qui apparemment lorsqu'un Pipedreader Est impliqué des causes de vote - vous attendez explicitement le écrivain sur affleurant . La documentation est claire que flush entraîne un lecteur s à notifier.

Je ne sais pas comment exécuter votre code pour que je ne puisse pas entrer de plus en plus profondément. J'espère que cela aide.


1 commentaires

Mon cas d'utilisation est qu'il existe plusieurs lecteurs pour quel processus Processus , et chacun de ces lecteurs a besoin de sa propre copie du flux, à partir du moment actuel et se terminant lorsque le lecteur est fermé. Différents lecteurs pour ne pas s'affronter mutuellement. Celui qui lisant la pipedreader est par exemple de sortieReader.waitforoutput () . L'écrivain est ReaderowriterCopier . Le programme principal est sbtrunner et les sources de test ont sbtrunnerter qui l'utilise. SBT représente code.google.com/p/simple-build-tool



7
votes

Le problème était que lorsque quelque chose est écrit sur le PipedWriter, il n'indique pas automatiquement la PIPEDREADER qu'il existe des données à lire. Lorsque l'on essaie de lire PipeDreader et que le tampon est vide, la pipedreader boucle et attendre à l'aide d'un appel wait (1000) appeler jusqu'à ce que le tampon ait des données.

La solution consiste à appeler pipedwriter.flush () toujours après avoir écrit quelque chose sur le tuyau. Tout ce que le flush est appelé notifier () sur le lecteur. La solution au code en question ressemble à ce .

(Pour moi, la mise en œuvre de PipedReader / PipedWriter ressemble beaucoup à un cas d'optimisation prématurée - pourquoi ne pas notifier à chaque écriture? Les lecteurs attendent également dans une boucle active, se réveillant chaque seconde, au lieu de se réveiller que lorsqu'il y a Quelque chose à lire. Le code contient également des commentaires de TODO, que la détection de filetage de lecteur / écrivain qui ne soit pas assez sophistiquée.)

Ce même problème semble également être également dans PipedOutPutStream < / a>. Dans mon projet actuel appelant flush () manuellement n'est pas possible (ne peut pas modifier les communes IO's ioutils.copy () ), donc je l'ai résolu en créant emballages de latence pour les classes de tuyaux. Ils travaillent beaucoup mieux que les cours d'origine. : -)


0 commentaires