对象序列化和piped broken异常问题

hrtc 2007-11-16 09:43:46
问题1:用ObjectOutputStream对象的writeObject写一个对象时,该对象必须new出来,如果只是修改对象的某一成员的话,用ObjectInputStream读出来的还是先前的对象,这是为什么?
问题2:编了一个网络通讯程序,pipedinputstream只用来同步2个线程,一个把接收到的客户端数据对象写入管道,另一个从管道中获得数据对象发向客户端,注:管道和socket没有关系,只是同步服务器的两个读写线程读写数据对象,当任何一个客户端关闭后(因为同步流,socket会抛异常),pipedinputstream的读方法(用ObjectInputStream包装过了)会抛Piped Broken异常,不明白为什么会抛异常。
由于代码太多,编了个测试代码贴上来,不过也够多了。希望高手赐教。
//用来序列化的对象
import java.io.Serializable;

public class BasicPacket implements Serializable {

private static final long serialVersionUID = 1L;

public boolean close;

public String time;

public String ip;

public BasicPacket(boolean close) {
this.close = close;
}

}

//主程序
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class MyTest {
public static void main(String[] args) {
new MyTest();
}

public MyTest() {
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = null;
ObjectOutputStream oos = null;

try {

pis = new PipedInputStream(pos);
oos = new ObjectOutputStream(pos);

Thread1 t1 = new Thread1(pis);

Thread2 t2 = new Thread2(oos);

t1.start();
t2.start();

System.out.println("thread start");

Thread.sleep(5000);
//关闭正在sleep的线程以抛出piped broken异常,实际程序中和这里不一样,但抛出的异常相同
//不明白线程异常为何会导致piped broken异常?
t2.interrupt();
t2.end();
t1.join();
t2.join();


System.out.println("thread end");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (pis != null) {
try {
pis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

// 读
class Thread1 extends Thread {
private PipedInputStream pis = null;

private boolean flag = false;

public void end() {
flag = false;
}

public Thread1(PipedInputStream pis) throws Exception {
this.pis = pis;
}

public void run() {
flag = true;
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(pis);
while (flag) {

Object obj = (Object)ois.readObject();
if(obj instanceof BasicPacket){
BasicPacket packet = (BasicPacket)obj;
//读出的对象
System.out.println("read:" + packet.ip);
}

}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (ois != null) {
try {
ois.close();
ois = null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

}
}

//写
class Thread2 extends Thread {
private ObjectOutputStream oos = null;


private boolean flag = false;

public void end() {
flag = false;
}

public Thread2(ObjectOutputStream oos) throws Exception {
this.oos = oos;
}

public void run() {
flag = true;
int i = 0;


try {
//放这里每次都是第一次的数据,packet.ip 这个赋值没用
BasicPacket packet = new BasicPacket(false);
while (flag) {
//只有每次new一个对象,读出来的才是正确的,这是为什么? //BasicPacket packet = new BasicPacket(false);
i = i + 1 % 100;
packet.ip = String.valueOf(i);;

synchronized (oos) {
oos.writeObject(packet);
oos.flush();
}
System.out.println("send:" + packet.ip);
//为了能睡觉时被打断,会抛异常,这个应该众所周知吧,java核心卷里写着
sleep(2000);
}
} catch (Exception e) {
e.printStackTrace();
}

}
}


}
...全文
67 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
hrtc 2007-11-26
  • 打赏
  • 举报
回复
发现只要有piped的线程退出就会抛异常,即使piped是在线程外new的,线程正常退出,怀疑是线程退出时,piped接收到notify通知导致,序列化问题貌似一组对象流连接中,上次序列化过的对象,会根据hashcode判断,如已经序列化就不会再序列化了,不知到是不是这原因,唉,怎么没人回答的,多谢2为帮我顶。
silver_zhao 2007-11-19
  • 打赏
  • 举报
回复
ding
lilifb 2007-11-17
  • 打赏
  • 举报
回复
MARK

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧