快速业务通道

彻底转变流,第1部分 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-16

private static InputStream pipedCompress (final InputStream in)    throws IOException {   PipedInputStream source = new PipedInputStream ();   final OutputStream out =    new GZIPOutputStream (new PipedOutputStream (source));   new Thread () {    public void run () {     try {      Streams.io (in, out);      out.close ();     } catch (IOException ex) {      ex.printStackTrace ();     }    }   }.start ();   return source; }

理论上,这可能是个好技术:通过使用线程(一个执行压缩,另一个处理产 生的数据),应用程序可以从硬件 SMP(对称多处理)或 SMT(对称多线程)中 受益。另外,这一解决方案仅涉及两个缓冲区写操作:I/O 循环将数据从输入流 读入缓冲区,然后通过压缩流写入 PipedOutputStream 。接着,输出流将数据 存储在内部缓冲区中,与 PipedInputStream 共享缓冲区以供应用程序读取。而 且,因为数据通过固定缓冲区流动,所以从不需要将它们完全读入内存中。事实 上,在任何给定时刻,缓冲区都只存储小部分的工作集。

不过,实际上,它的性能很糟糕。管道式流需要利用同步,从而引起两个线 程之间激烈争夺同步。它们的内部缓冲区太小,无法有效地处理大量数据或隐藏 锁争用。其次,持久共享缓冲区会阻碍许多简单的高速缓存策略共享 SMP 机器 上的工作负载。最后,线程的使用使得异常处理极其困难:没有办法将可能出现 的任何 IOException 下推到管道中以便阅读器处理。总之,这一解决方案太难 处理,根本不实际。

彻底转变流,第1部分(4)

时间:2011-06-21 Merlin Hughes

工程解决方案

现在,我们将研究另一种解决该问题的工程方案。这种解决方案提供了一个 特地为解决这类问题而设计的框架,该框架提供了对数据的 InputStream 访问 ,这些数据是从递增地向 OutputStream 写入数据的源中产生的。递增地写入数 据这一事实很重要。如果源在单个原子操作中将所有数据都写入 OutputStream ,而且如果不使用线程,则我们基本上又回到了蛮力技术的老路上。不过,如果 可以访问源以递增地写入其数据,则我们就实现了在蛮力和管道式流解决方案之 间的良好平衡。该解决方案不仅提供了在任何时候只在内存中保存少量数据的管 道式优点,同时也提供了避免线程的蛮力技术的优点。

图 4 演示了完整的解决方案。我们将在本文的剩余部分研究 该解决方案的 源代码。

图 4. 工程解决方案

彻底转变流,第1部分 - 编程入门网

输出引擎

清单 4 提供了一个描述数据源的接口 OutputEngine 。正如我所说的,这些 源递增地将数据写入输出流:

清单 4. 输出引擎

package org.merlin.io; import java.io.*; /** * An incremental data source that writes data to an OutputStream. * * @author Copyright (c) 2002 Merlin Hughes <merlin@merlin.org> * * This program is free software; you can redistribute * it and/or modify it under the terms of the GNU * General Public License as published by the Free * Software Foundation; either version 2 * of the License, or (at your option) any later version. */ public interface OutputEngine {   public void initialize (OutputStream out) throws IOException;   public void execute () throws IOException;   public void finish () throws IOException; }

initialize() 方法向该引擎提供一个流,应该向这个流写入数据。然后,重 复调用 execute() 方法将数据写入该流中。当数据写完时,引擎会关闭该流。 最后,当引擎应该关闭时,将调用 finish() 。这会发生在引擎关闭其输出流的 前后。

彻底转变流,第1

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号