Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Probleme mit PipedInputStream: java.io.InterruptedIOException

2 views
Skip to first unread message

Maximilian

unread,
Jun 28, 2008, 7:43:25 AM6/28/08
to
Hallo,

ich beschäftige mich zum ersten mal mit den PipedStreams und habe ein
Paar kleine Probleme. Ich habe eigentlich ein klassisches szenario. Ein
Thread produziert Daten und sendet sie über einen PipedStream an den 2.
Thread, der die Daten verarbeitet (anzeigt in meinem Fall). Das
Funktioniert auch soweit gut, wenn ich jetzt aber die daten
zeitverzögert durch die Pipe schicke (mit 500 Millisekunden z.B.), dann
bekomme ich eine java.io.InterruptedIOException beim Read-Vorgang im
verarbeitenden Thread. Ich habe herausgefunden, dass ein Aufruf von
.avialable() bei dem DataInputStream Objekt, das über dem
PipedInputStream sitzt unmittelbar vor dem Fehler 0 ergibt (was ja
bedeutet, dass im moment keine Daten zu lesen sind). Kann es damit zu
tun haben? Ich dachte immer dass mein DataInputStream in der readXY()
Methode wartet, wenn nichts zu lesen ist, bis neue zu lesende Daten da
sind. Ich würde mich über Hinweise und Gedankenanstöße freuen.

mit freundlichen Grüßen

Maximilian E

Lothar Kimmeringer

unread,
Jun 28, 2008, 8:04:44 AM6/28/08
to
Maximilian wrote:

> ich beschäftige mich zum ersten mal mit den PipedStreams und habe ein
> Paar kleine Probleme. Ich habe eigentlich ein klassisches szenario. Ein
> Thread produziert Daten und sendet sie über einen PipedStream an den 2.
> Thread, der die Daten verarbeitet (anzeigt in meinem Fall). Das
> Funktioniert auch soweit gut, wenn ich jetzt aber die daten
> zeitverzögert durch die Pipe schicke (mit 500 Millisekunden z.B.), dann
> bekomme ich eine java.io.InterruptedIOException beim Read-Vorgang im
> verarbeitenden Thread.

Der Grund warum eine InterruptedIOException geworfen wird, wird in
den Javadocs eigentlich recht gut erklaert:

| Signals that an I/O operation has been interrupted. An
| InterruptedIOException is thrown to indicate that an input
| or output transfer has been terminated because the thread
| performing it was interrupted. The field bytesTransferred
| indicates how many bytes were successfully transferred before
| the interruption occurred.

Irgendwo scheint bei Dir ein Thread zu sterben.

> Ich habe herausgefunden, dass ein Aufruf von
> .avialable() bei dem DataInputStream Objekt, das über dem
> PipedInputStream sitzt unmittelbar vor dem Fehler 0 ergibt (was ja
> bedeutet, dass im moment keine Daten zu lesen sind).

So soll es sein, wenn Du Daten zeitversetzt sendest.

> Kann es damit zu
> tun haben?

Nein.

> Ich dachte immer dass mein DataInputStream in der readXY()
> Methode wartet, wenn nichts zu lesen ist, bis neue zu lesende Daten da
> sind.

Das ist auch so, daher kann das nicht der Grund sein.

> Ich würde mich über Hinweise und Gedankenanstöße freuen.

Ich wuerde einfach mal behaupten, dass der Thread, der die Daten
schreibt, 500 ms wartet, dann schreibt, den Stream evtl. schliesst
und dann stirbt. Um sagen zu koennen, ob das in so einem Fall
zu einer Exception fuehrt, muesste man Deinen Source kennen (und
in die Sourcen von PipedInputStream schauen, um zu sehen, wann
genau die Exception erzeugt wird).


Gruesse, Lothar
--
Lothar Kimmeringer E-Mail: spam...@kimmeringer.de
PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
questions!

Maximilian

unread,
Jun 28, 2008, 8:24:07 AM6/28/08
to
Lothar Kimmeringer schrieb:

> Maximilian wrote:
>
>> ich beschäftige mich zum ersten mal mit den PipedStreams und habe ein
>> Paar kleine Probleme. Ich habe eigentlich ein klassisches szenario. Ein
>> Thread produziert Daten und sendet sie über einen PipedStream an den 2.
>> Thread, der die Daten verarbeitet (anzeigt in meinem Fall). Das
>> Funktioniert auch soweit gut, wenn ich jetzt aber die daten
>> zeitverzögert durch die Pipe schicke (mit 500 Millisekunden z.B.), dann
>> bekomme ich eine java.io.InterruptedIOException beim Read-Vorgang im
>> verarbeitenden Thread.
>
> Der Grund warum eine InterruptedIOException geworfen wird, wird in
> den Javadocs eigentlich recht gut erklaert:
>
> | Signals that an I/O operation has been interrupted. An
> | InterruptedIOException is thrown to indicate that an input
> | or output transfer has been terminated because the thread
> | performing it was interrupted. The field bytesTransferred
> | indicates how many bytes were successfully transferred before
> | the interruption occurred.
>
> Irgendwo scheint bei Dir ein Thread zu sterben.

Das kann eigentlich nicht sein. Es gibt den Hauptthread (in dem die main
Methode aufgerufen wird) und einen weiteren Thread (an den die Daten
gesendet werden und wo sie verarbeitet werden). Im "neben"-Thread
entsteht aber der Fehler beim lesen und nur dieser Thread schlißt mit
.close() die Streams. Im Debugger konnte ich das Problem übrigens nicht
reproduzieren, es lief hier alles einwandfrei.

>> Ich habe herausgefunden, dass ein Aufruf von
>> .avialable() bei dem DataInputStream Objekt, das über dem
>> PipedInputStream sitzt unmittelbar vor dem Fehler 0 ergibt (was ja
>> bedeutet, dass im moment keine Daten zu lesen sind).
>
> So soll es sein, wenn Du Daten zeitversetzt sendest.
>
>> Kann es damit zu
>> tun haben?
>
> Nein.
>
>> Ich dachte immer dass mein DataInputStream in der readXY()
>> Methode wartet, wenn nichts zu lesen ist, bis neue zu lesende Daten da
>> sind.
>
> Das ist auch so, daher kann das nicht der Grund sein.

Das ist sehr beruhigend.

>
>> Ich würde mich über Hinweise und Gedankenanstöße freuen.
>
> Ich wuerde einfach mal behaupten, dass der Thread, der die Daten
> schreibt, 500 ms wartet, dann schreibt, den Stream evtl. schliesst
> und dann stirbt. Um sagen zu koennen, ob das in so einem Fall
> zu einer Exception fuehrt, muesste man Deinen Source kennen (und
> in die Sourcen von PipedInputStream schauen, um zu sehen, wann
> genau die Exception erzeugt wird).

hier mal die genaue Fehlermeldung:

java.io.InterruptedIOException
at java.io.PipedInputStream.read(PipedInputStream.java:262)
at java.io.PipedInputStream.read(PipedInputStream.java:305)
at java.io.DataInputStream.readFully(DataInputStream.java:176)
at java.io.DataInputStream.readLong(DataInputStream.java:380)
at java.io.DataInputStream.readDouble(DataInputStream.java:428)
at slaves.SimplePlotSlave.run(SimplePlotSlave.java:57)

und die Methode in der die Exception geworfen wird in PipedInputStream:

/**
* Reads the next byte of data from this piped input stream. The
* value byte is returned as an <code>int</code> in the range
* <code>0</code> to <code>255</code>. If no byte is available
* because the end of the stream has been reached, the value
* <code>-1</code> is returned. This method blocks until input data
* is available, the end of the stream is detected, or an exception
* is thrown.
* If a thread was providing data bytes
* to the connected piped output stream, but
* the thread is no longer alive, then an
* <code>IOException</code> is thrown.
*
* @return the next byte of data, or <code>-1</code> if the end
of the
* stream is reached.
* @exception IOException if the pipe is broken.
*/
public synchronized int read() throws IOException {
if (!connected) {
throw new IOException("Pipe not connected");
} else if (closedByReader) {
throw new IOException("Pipe closed");
} else if (writeSide != null && !writeSide.isAlive()
&& !closedByWriter && (in < 0)) {
throw new IOException("Write end dead");
}

readSide = Thread.currentThread();
int trials = 2;
while (in < 0) {
if (closedByWriter) {
/* closed by writer, return EOF */
return -1;
}
if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) {
throw new IOException("Pipe broken");
}
/* might be a writer waiting */
notifyAll();
try {
wait(1000);
} catch (InterruptedException ex) {
throw new java.io.InterruptedIOException();
}
}
int ret = buffer[out++] & 0xFF;
if (out >= buffer.length) {
out = 0;
}
if (in == out) {
/* now empty */
in = -1;
}
return ret;
}

vielen Dank für die Hilfe bis jetzt.

Grüße

Maximilian

Maximilian

unread,
Jun 28, 2008, 8:35:08 AM6/28/08
to
Um vielleicht die Zeile des Fehler zu präzisieren:

throw new java.io.InterruptedIOException(); //<-- HIER IST DER
FEHLER

Maximilian

unread,
Jun 28, 2008, 8:42:03 AM6/28/08
to
Maximilian schrieb:

So ich bin schon ein bisschen näher an der Ursache:
Die InterruptedIOException wird ja durch eine InterruptedException
ausgelöst. Die InterruptedException wird durch meinen interrupt() Befehl
ausgelöst wird. Ich dachte der wäre ganz bequem um einen Thread sachte
zu beenden (in meiner Schleife in der Run-Methode frage ich einfach
isInterrupted() ab und ob nicht noch etwas zu lesen ist (mit
avialable()). Wenn nix mehr da ist und auch der Thread interrupted ist,
dann könnte ich ja theoretisch beenden. Das ist mir jetzt wohl zum
Verhängins geworden.
Was ist nun eine gute Alternative zu meiner interrupt() Version? Selber
eine Boolean aufsetzen die ich in der Schleife abfrage?

Grüße


Maximilian

Achim Peters

unread,
Jun 28, 2008, 9:02:42 AM6/28/08
to
Maximilian wrote:
> Um vielleicht die Zeile des Fehler zu präzisieren:
> try {
> wait(1000);
> } catch (InterruptedException ex) {
> throw new java.io.InterruptedIOException(); //<-- HIER IST DER
> FEHLER

Aber das ist doch nicht

| beim Read-Vorgang

wie Du schriebst, sondern bei einem Object#wait()!? Da hat ein anderer
Thread von Dir ein interrupt() gemacht:

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#wait(long)

Bye
Achim

Maximilian

unread,
Jun 28, 2008, 9:10:57 AM6/28/08
to
Achim Peters schrieb:

> Maximilian wrote:
>> Um vielleicht die Zeile des Fehler zu präzisieren:
>> try {
>> wait(1000);
>> } catch (InterruptedException ex) {
>> throw new java.io.InterruptedIOException(); //<-- HIER IST DER
>> FEHLER
>
> Aber das ist doch nicht
>
> | beim Read-Vorgang
>
> wie Du schriebst, sondern bei einem Object#wait()!? Da hat ein anderer
> Thread von Dir ein interrupt() gemacht:

Es ist zumindest in der Read-Methode. Aber ja du hast mehr recht. Dass
ein anderer Thread mir einen interrupt() macht habe ich selbst weiter
oben schon festgestellt. Jetzt geht es darum eine alternative zu
interrupt() zu finden. Ich habe jetzt einfach eine Endlosschleife in der
Run-Methode gemacht und das interrupt() entfernt. Jetzt geht soweit
alles nur schön ist es nicht und am Schlus passiert mir immer noch eine
"java.io.IOException: Write end dead".

Grüße

Maximilian
>
> http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#wait(long)
>
> Bye
> Achim

Lothar Kimmeringer

unread,
Jun 29, 2008, 6:32:16 AM6/29/08
to
Maximilian wrote:

> So ich bin schon ein bisschen näher an der Ursache:
> Die InterruptedIOException wird ja durch eine InterruptedException
> ausgelöst. Die InterruptedException wird durch meinen interrupt() Befehl
> ausgelöst wird.

Das ist damit gemeint, als in der Javadoc von "interrupted" ge-
sprochen wurde ;-)

> Ich dachte der wäre ganz bequem um einen Thread sachte
> zu beenden (in meiner Schleife in der Run-Methode frage ich einfach
> isInterrupted() ab und ob nicht noch etwas zu lesen ist (mit
> avialable()).

Zum isInterrupted kommst Du aber nie, da dies ja schon im
read() zum Verhaengnis wurde.

> Was ist nun eine gute Alternative zu meiner interrupt() Version? Selber
> eine Boolean aufsetzen die ich in der Schleife abfrage?

boolean run = true;

public void run(){
while (run){
...
}
}

public void kill(){
run = false;
// evtl. andere Sachen, die dazu fuehren, dass die While-
// ueberpruefung ueberhaupt passiert

Maximilian

unread,
Jun 29, 2008, 7:00:11 AM6/29/08
to
Lothar Kimmeringer schrieb:

>> Was ist nun eine gute Alternative zu meiner interrupt() Version? Selber
>> eine Boolean aufsetzen die ich in der Schleife abfrage?
>
> boolean run = true;
>
> public void run(){
> while (run){
> ...
> }
> }
>
> public void kill(){
> run = false;
> // evtl. andere Sachen, die dazu fuehren, dass die While-
> // ueberpruefung ueberhaupt passiert
> }

Super danke das sieht elegant aus. Muss ich kill selber aufrufen oder
macht passiert das irgendwie automatisch (naja das kann ich ja auch in
den docs nachlesen)?

Grüße

Maximilian

Lothar Kimmeringer

unread,
Jun 29, 2008, 9:03:39 AM6/29/08
to
Maximilian wrote:

> Super danke das sieht elegant aus. Muss ich kill selber aufrufen oder
> macht passiert das irgendwie automatisch (naja das kann ich ja auch in
> den docs nachlesen)?

Das kill ist eine von Dir geschriebene Methode, die natuerlich
von Dir selbst aufgerufen werden muss. Um sicherzugehen, solltest
Du den Thread dann noch mittels setDaemon(true) als Daemon-Thread
hochfahren, dann wird er z.B. von der Virtual Machine abgeraeumt,
wenn sie sich beendet. Das waere dann auch einer dieser Faelle,
wo das read() mittels InterruptedIOException aus dem Schlaf
gerissen wird.

0 new messages