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

Object streams wrapping pipe streams

9 views
Skip to first unread message

Jochelee

unread,
Apr 29, 2002, 5:06:52 PM4/29/02
to
Hi!

This is the problem: I have created a Pipe with its two ends, a
PipedInputStream called pis, and a PipedOutputStream called pos.
I wrap pis with an ObjectInputStream called ois, and pos with an
ObjectOutputStream called oos.
There's one thread in charge of reading objects (I've created a Serializable
class to customize some
events. Nothing to do with the Event class), but I want two (or more)
threads to send these objects through the pipe (they have a reference to
oos). I've used the pipes because I need a blocking behaviour when reading
the events (similar to a C 'select', I think).
The problem is (I think) that when one of the writer threads dies (because
the threads ends), the pipe gets closed, so the reading throws an exception.
Is this normal? I have still two references to oos, one in the other writer,
and another in the reader, where I created all the objects.
I've tried to get around this problem writing a class whose only attribute
is the mentioned ObjectOutputStream oos, so all the writer references point
to this new object, instead of directly to oos. It didn't work.

I can't really reach to know what's going on.
Do you have any idea of what's happening, and how to make it work?

Thank you very much!!

Gordon Beaton

unread,
Apr 29, 2002, 8:57:21 AM4/29/02
to
On Mon, 29 Apr 2002 14:06:52 -0700, Jochelee wrote:
> I have created a Pipe with its two ends, a PipedInputStream called
> pis, and a PipedOutputStream called pos. I wrap pis with an
> ObjectInputStream called ois, and pos with an ObjectOutputStream
> called oos.
>
> There's one thread in charge of reading objects (I've created a
> Serializable class to customize some events.

[...]

> I want two (or more) threads to send these objects through the pipe
> (they have a reference to oos).

I wonder why you want to serialize your objects when you are only
sending them between threads in the same JVM?

It would be much simpler, more efficient and less error prone to pass
the object references directly, either by invoking methods in the
reader, or by using an object queue to connect the writers with the
reader.

> The problem is (I think) that when one of the writer threads dies
> (because the threads ends), the pipe gets closed, so the reading
> throws an exception. Is this normal? I have still two references to
> oos, one in the other writer, and another in the reader, where I
> created all the objects.

I think your analysis of the situation is wrong. The fact that your
thread dies will not cause the ObjectOutputStream to close, in fact it
will not directly affect any objects except the thread itself. More
likely it's the other way around, i.e. an exception is raised when
writing, causing the thread to terminate.

Do you attempt to synchronize access to the ObjectOutputStream when
you write to it from more than one thread?

At any rate we can only speculate unless you post a simple, real
example. Also, cut and paste the exception you get, don't just
describe it.

/gordon

--
[ do not send me private copies of your followups ]
g o r d o n . b e a t o n @ e r i c s s o n . c o m

nos...@nospam.com

unread,
Apr 29, 2002, 10:28:05 AM4/29/02
to
(reply in the bottom)

Yes, you're right...Sorry for a post so vague.
Here are the classes. Probably my approach is not the best, but anyway,
I would like to know what's going on

///// mainThread.java ////////////////////////////////////
import java.io.*;

public class mainThread {

public static void main(String args[]) {

try {
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream(pis);
ObjectOutputStream oos = new ObjectOutputStream(pos);
ObjectInputStream ois = new ObjectInputStream(pis);
alarmThread at = new alarmThread(oos, 1000, alarmThread.ONCE); //If
PERIODIC, no exception
pipedEvent pev;

while ((pev=(pipedEvent)ois.readObject())!=null) {
System.out.println("Event!: "+pev);
}
} catch (Exception e) {
e.printStackTrace();
}
}

}

//// alarmThread.java ///////////////////////
import java.io.*;

public class alarmThread extends Thread {

public static final int PERIODIC=1;
public static final int ONCE=2;

protected int alarmType;
protected int sleepTime;
protected ObjectOutputStream oos;

public alarmThread(ObjectOutputStream os, int time, int aType) {
try {
oos = os;
sleepTime = time;
alarmType = aType;
this.start();
} catch (Exception e) {
System.err.println("Error creating alarmThread!");
e.printStackTrace();
}

}

public void run() {
try {
if (alarmType==PERIODIC) {
while (true) {
sleep(sleepTime);
oos.writeObject(new pipedEvent(pipedEvent.TIME_OUT, new
String("PERIODIC Time's up!")));
oos.flush();
}
} else if (alarmType==ONCE) {
sleep(sleepTime);
oos.writeObject(new pipedEvent(pipedEvent.TIME_OUT, new
String("ONCE Time's up!")));
oos.flush();
} else {
System.err.println("Alarm type not supported!!");
}
} catch (Exception e) {
e.printStackTrace();
}
}

public void finalize() { System.out.println("alarmThread dying"); }
}

/////////////// pipedEvent.java /////////////////////
import java.io.*;

public class pipedEvent implements Serializable {

protected int type;
protected String event;

public pipedEvent(int t, String e) {
type = t;
event = e;
}

public final static int SOCKET_DATA=1;
public final static int TIME_OUT=2;
// Any other kind of event...

public String toString() {
return new String("Type:"+type+" event:"+event);
}

public int getType() { return type; }
public String getEvent() { return event; }
}

////////////////////////////////////

In this example, here's the message that appears after execution (when
the alarmThread dies):

Event!: Type:2 event:ONCE Time's up!
java.io.IOException: Pipe broken
at java.io.PipedInputStream.read(PipedInputStream.java)
at java.io.ObjectInputStream.peekCode(ObjectInputStream.java)
at java.io.ObjectInputStream.refill(ObjectInputStream.java)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java)
at mainThread.main(mainThread.java:15)

What's going on??


Thank you very much!!!

Gordon Beaton

unread,
Apr 29, 2002, 11:22:24 AM4/29/02
to
On Mon, 29 Apr 2002 16:28:05 +0200, nos...@nospam.com wrote:
> Yes, you're right...Sorry for a post so vague. Here are the classes.
> Probably my approach is not the best, but anyway, I would like to
> know what's going on

A quick look at the source for PipedInputStream.read() reveals that
there is a test whether the writer Thread is still alive, and if not,
to throw the IOException("pipe broken") that you get.

The class does not seem to take into account that there can be more
than one writer Thread, or that there might appear a new writer later
(because you are still holding a reference). The concept of
connectedness looks rather primitive.

Personally I wouldn't use this class, and as I mentioned earlier I
think that a queue of objects is more suitable for what you are doing.
Use java.util.LinkedList for that. Don't forget to synchronize when
you have more than one writer.

/gordon

0 new messages