Il problema è che quando qualcosa viene scritto nel PipedWriter, non notificare automaticamente la PipedReader che ci sono alcuni dati da leggere. Quando si tenta di leggere PipedReader e il buffer è vuoto, PipedReader eseguirà un ciclo e attenderà utilizzando una chiamata wait(1000)
fino a quando il buffer non avrà alcuni dati.
La soluzione è quella di chiamare PipedWriter.flush()
sempre dopo aver scritto qualcosa al tubo. Tutto ciò che fa il flush è chiamare notifyAll()
sul lettore. La correzione del codice in questione looks like this.
(Per me l'implementazione di PipedReader/PipedWriter assomiglia molto a un caso di ottimizzazione prematura - perché non notificare All in ogni scrittura? Anche i lettori attendono in un ciclo attivo, svegliandosi ogni secondo, invece di svegliarsi solo quando è qualcosa da leggere. Il codice contiene anche alcuni commenti, che il rilevamento del thread reader/writer non è abbastanza sofisticato.)
Questo stesso problema sembra essere anche in PipedOutputStream. Nel mio attuale progetto chiamare flush()
manualmente non è possibile (non è possibile modificare i Commons IO IOUtils.copy()), quindi l'ho risolto creando low-latency wrappers per le classi di pipe. Funzionano molto meglio delle classi originali. :-)
fonte
2010-05-16 17:20:34
Questo potrebbe non essere quello che vuoi, ma il thread di scrittura sarebbe in grado di notificare il thread di lettura dopo aver scritto qualcosa? E il thread di lettura continuerà a leggere mentre 'ready()' è vero, quindi dormi quando non lo è? – Phil
Puoi mostrarci il tuo codice, per favore?Il 'wait (1000)' non dovrebbe essere il problema, perché lo scrittore notifica al lettore quando qualcosa è scritto. Il lettore allora fugge dalla sua attesa(). – tangens
Grazie, Phil. In questo momento non sono a casa, quindi non posso testarlo, ma basandomi sul codice sorgente, PipedWriter.flush() sembra notificare i lettori. Ci proverò più tardi oggi. –