在有一部分传输的时候,为了效率我们需要将一个输入流中的数据异步写出到多个输出流里面,Java 自带的IO/NIO并没有这个功能,自己实现的具体流程图如下:
可以想到,如果达到这个效果,我们需要将输入流中的读出的byte[] 保存到内存中,之后再由输出流读取,如果希望输入流输出流互不干涉完全异步,那么我们就需要每个输出流一个线程来实现,输入流不停地向缓冲区队列里面写数据,不用管输出流怎么读,直到所有数据读完。
输入流在第一次读数据之后输出流开始启动,输出流监控这个缓冲队列,如果有数据就读取,没有数据就进入wait状态。这里我是这样实现的:输出流在从缓冲区中读取并写出一个数据块之后,即进入wait状态,如果发现输入流已经读取完了所有数据就不必要wait了;输入流在读取一个数据块之后,notify一次所有的输出流线程,从而达到这个效果。
这个原理不难看出,如果我们不对这个缓冲区定时清理的话,那么它必然会达到整个输入流所有数据量的大小,也就是说,如果输入流是一个文件,那么最终这个文件会被完全读取到内存中,如果情况特殊这个文件有几个G,那么内存就会崩掉,所以我们需要定时的去清理这个缓冲区,如果一个数据块已经被所有输出流线程读取过了,那么我们就可以将它从内存中移除掉,让JVM自动回收掉。注意我这里的描述,是所有输出线程全部读取过,如果情况特殊有一个输出流线程进入卡死或者等待状态,那么依然会出现上述情况。之前准备用双向循环链表来实现这个缓冲区,这样清理会比较快一点,但是LinkedList将它的核心Node对象封装起来了,退而求其次我这里就用hashMap来实现的。
具体实现起来还有很多小问题,我已经在代码里面相应的地方给出清楚的注释了,有兴趣的话可以去我的资源里面下载:
http://download.csdn.net/detail/zhwwanwan/7762977
一个输入流同时写出到多个输出流,布布扣,bubuko.com