读取ObjectInputStream的阻塞问题,在线等,急!

liudows 2005-05-22 10:40:12
我碰到的问题是这样的:要从网络上读取信息,对方发来的是序列化过后的对象,我要用ObjectInputStream来读取,但是我发现ObjectInputStream是非阻塞式的。这样我就不知道对方什么时候发过来,所以我不得不用一个for(;;)循环来读取,但是这样的话CPU占用100%。请问有什么办法可以解决这个问题?
...全文
562 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
axing941021 2005-07-27
  • 打赏
  • 举报
回复
线程要休眠的,要不100%占用CPU Thread.sleep(1000)
cwjfzu 2005-05-26
  • 打赏
  • 举报
回复
上面写错
要把有这个循环的类,写在线程里面
这样就算有死循环
主线程也不会阻塞!
cwjfzu 2005-05-26
  • 打赏
  • 举报
回复
要把有这个循环的类,写在循环!
liudows 2005-05-24
  • 打赏
  • 举报
回复
问题应该是这样的,读网络信息的语句是message = (Content)(oin.readObject());,其中readObject函数不能实现阻塞式读取,当读到流的末尾时就会抛出EOFException异常。由于我又用for(;;)来循环读取,所以CPU占用率就达到100%了。看来不能用序列化流从网络上直接读取消息。
gtlang78 2005-05-24
  • 打赏
  • 举报
回复
是不是读的时候抛异常了?

catch (ClassNotFoundException e)
{}
catch (IOException e)
{}

把e.printStackTrace();加上看看吧
cwjfzu 2005-05-24
  • 打赏
  • 举报
回复
除了监听线程之外,还可以设立处理进程
这样就不会影响主界面

楼主讲一下你的结构
liudows 2005-05-22
  • 打赏
  • 举报
回复
不如我把代码贴出来吧,大伙帮我看看。可能细节上有些问题,但是总体结构就是这样的拉:
netAdapter.java

class netAdapter
{

BufferedInputStream input = new BufferedInputStream(socket.getInputStream());
BufferedOutputStream output = new BufferedOutputStream(socket.getOutputStream());
ObjectInputStream oin = new ObjectInputStream(input);
ObjectOutputStream oout = new ObjectOutputStream(output);

public Message receive()
{
Message message = null;
try
{
message = (Content)(oin.readObject());
}
catch(ClassNotFoundException cnfe)
{
System.out.println("class Content not Found");
throw cnfe;
}
catch(EOFException eofe)
{
System.out.println("end of stream");
throw eofe;
}
catch(IOException ioe)
{
System.out.println("I/O err in receive() - " + ioe);
throw ioe;
}
}
}

main.java

public static void main(String[] args)
{
Runnable netRunnable = new Runnable()
{
public void run()
{
Message message;
netAdapter nadapter = new netAdapter();
for(;;)
{
try{
if(nadapter != null)
{
message = null;
message = nadapter.receive();
message.handle();
}
}
catch (ClassNotFoundException e)
{}
catch (IOException e)
{}
}
}
};

Thread netThread = new Thread(client.netRunnable);
netThread.start();

.....//do something in user interface
}
liudows 2005-05-22
  • 打赏
  • 举报
回复
就是写在另一个线程里的,但是整个程序响应还是很慢,界面几乎动不了,怎么办啊
zhudonhua 2005-05-22
  • 打赏
  • 举报
回复
支持楼上,新开一个线程去监视网络流,当读到对象时通知主线程去调用读取操作
cwjfzu 2005-05-22
  • 打赏
  • 举报
回复
把那个要阻塞的操作写在线程里面,这样就不会占用主线程了

这样做叫做监听线程
InputStream |--FileInputStream/:文件输入流。从文件系统中的某个文件中获得输入字节。用于读取图像,声音,视频等数据类的原始字节流。 | |--FilterInputStream/:包含一些输入流,将这些流用作其基本数据源,可以直接传输数据或者提供额外的功能。 | |--BufferedInputStream/:输入流缓冲区。 | 为另一个输入流添加一些功能,创建一个缓冲区,支持mark和reset方法。 | mark操作记录输入流中的某个点,reset操作在从包含的输入流获取新字节前,再读取最后一次。 |--DataInputStream/:用于操作基本数据类型数据的对象,应用程序可以使用数据输入流写入稍后有数据输入流读取的数据。 | |--ObjectInputStream/:对象的序列化。用于操作对象的流,将一个具体的对象进行持久化写入到硬盘上。 | |--PipedInputStream/:管道流。管道读取流可以读取管道写入流的数据。注意:需要加多线程技术,否则会发生死锁。read方法是阻塞式的。 | |--ByteArrayInputStream/:字节数组输入流。操作的都是内存中的数组,所以不需要关闭。把数组封装到流中,可以提供更多的方法操作数组。 | |--SequenceInputStream/:序列流。将多个读取流合并成一个读取流,可以方便操作多个读取流。原理(迭代器)。 OutputStream |--FileOutputStream/:文件输出流。用于将写入File和FileDescriptor的输出流。用来操作图像,声音,视频等原始字节流。 | |--FilterOutputStream/:包含一些输出流,重写那些将请求传递给包含输出流OutputStream的所有方法。 | 其子类可以进一步重写这些方法并额外提供方法和字段。 |--BufferedOutputStream/:输出流缓冲区。 | 应用程序可以将各个字节写入底层输出流中,而不必每个字节每次都抵用底层系统。提高了输出的效率。 |--DataOutputStream/:数据输出流允许应用程序将基本数据类型写入到输出流中。应用程序可以使用输入流将数据读入。 | |--PrintStream/:为其他输出流添加了功能,方便打印各种数据值表示类型。PrintStream永远不会抛出IOException异常。 | 为了刷新可以创建一个新的PrintStream,调用println可以提供换行功能。使用了默认的字节编码。 |--ObjectOutputStream/:将java对象的基本数据类型和图形写入到OutputStream。 | |--PipedOutputStream/:可以将管道输出流连接到管道输入流来创建通信管道。 | 用方法connect(PipedInputStream snk) 将此管道输出流连接到接收者。 同样使用多线程技术,避免死锁。 |--ByteArrayOutputStream/:实现了一个输出流,其中的数据写入到一个byte数组。 | 使用toByteArray()和toString()获取数据。关闭无效,依然可以调用。不会产生任何IOException异常。

62,612

社区成员

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

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