知识大全 分析 Java I/O 的工作机制

Posted

篇首语:同时赶两只兔,一只也捉不到。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 分析 Java I/O 的工作机制相关的知识,希望对你有一定的参考价值。

分析 Java I/O 的工作机制  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  网络 I/O 优化

  网络 I/O 优化通常有一些基本处理原则

   一个是减少网络交互的次数 要减少网络交互的次数通常我们在需要网络交互的两端会设置缓存 比如 Oracle 的 JDBC 驱动程序 就提供了对查询的 SQL 结果的缓存 在客户端和数据库端都有 可以有效的减少对数据库的访问 关于 Oracle JDBC 的内存管理可以参考《 Oracle JDBC 内存管理》 除了设置缓存还有一个办法是 合并访问请求 如在查询数据库时 我们要查 个 id 我可以每次查一个 id 也可以一次查 个 id 再比如在访问一个页面时通过会有多个 js 或 css 的文件 我们可以将多个 js 文件合并在一个 HTTP 链接中 每个文件用逗号隔开 然后发送到后端 Web 服务器根据这个 URL 链接 再拆分出各个文件 然后打包再一并发回给前端浏览器 这些都是常用的减少网络 I/O 的办法

   减少网络传输数据量的大小 减少网络数据量的办法通常是将数据压缩后再传输 如 HTTP 请求中 通常 Web 服务器将请求的 Web 页面 gzip 压缩后在传输给浏览器 还有就是通过设计简单的协议 尽量通过读取协议头来获取有用的价值信息 比如在代理程序设计时 有 层代理和 层代理都是来尽量避免要读取整个通信数据来取得需要的信息

   尽量减少编码 通常在网络 I/O 中数据传输都是以字节形式的 也就是通常要序列化 但是我们发送要传输的数据都是字符形式的 从字符到字节必须编码 但是这个编码过程是比较耗时的 所以在要经过网络 I/O 传输时 尽量直接以字节形式发送 也就是尽量提前将字符转化为字节 或者减少字符到字节的转化过程

   根据应用场景设计合适的交互方式 所谓的交互场景主要包括同步与异步阻塞与非阻塞方式 下面将详细介绍

  同步与异步

  所谓同步就是一个任务的完成需要依赖另外一个任务时 只有等待被依赖的任务完成后 依赖的任务才能算完成 这是一种可靠的任务序列 要么成功都成功 失败都失败 两个任务的状态可以保持一致 而异步是不需要等待被依赖的任务完成 只是通知被依赖的任务要完成什么工作 依赖的任务也立即执行 只要自己完成了整个任务就算完成了 至于被依赖的任务最终是否真正完成 依赖它的任务无法确定 所以它是不可靠的任务序列 我们可以用打电话和发短信来很好的比喻同步与异步操作

  在设计到 IO 处理时通常都会遇到一个是同步还是异步的处理方式的选择问题 因为同步与异步的 I/O 处理方式对调用者的影响很大 在数据库产品中都会遇到这个问题 因为 I/O 操作通常是一个非常耗时的操作 在一个任务序列中 I/O 通常都是性能瓶颈 但是同步与异步的处理方式对程序的可靠性影响非常大 同步能够保证程序的可靠性 而异步可以提升程序的性能 必须在可靠性和性能之间做个平衡 没有完美的解决办法

  阻塞与非阻塞

  阻塞与非阻塞主要是从 CPU 的消耗上来说的 阻塞就是 CPU 停下来等待一个慢的操作完成 CPU 才接着完成其它的事 非阻塞就是在这个慢的操作在执行时 CPU 去干其它别的事 等这个慢的操作完成时 CPU 再接着完成后续的操作 虽然表面上看非阻塞的方式可以明显的提高 CPU 的利用率 但是也带了另外一种后果就是系统的线程切换增加 增加的 CPU 使用时间能不能补偿系统的切换成本需要好好评估

  两种的方式的组合

  组合的方式可以由四种 分别是 同步阻塞 同步非阻塞 异步阻塞 异步非阻塞 这四种方式都对 I/O 性能有影响 下面给出分析 并有一些常用的设计用例参考

  表 四种组合方式

  组合方式 

  性能分析 

  同步阻塞 

  最常用的一种用法 使用也是最简单的 但是 I/O 性能一般很差 CPU 大部分在空闲状态  

  同步非阻塞 

  提升 I/O 性能的常用手段 就是将 I/O 的阻塞改成非阻塞方式 尤其在网络 I/O 是长连接 同时传输数据也不是很多的情况下 提升性能非常有效 这种方式通常能提升 I/O 性能 但是会增加 CPU 消耗 要考虑增加的 I/O 性能能不能补偿 CPU 的消耗 也就是系统的瓶颈是在 I/O 还是在 CPU 上  

  异步阻塞 

  这种方式在分布式数据库中经常用到 例如在网一个分布式数据库中写一条记录 通常会有一份是同步阻塞的记录 而还有两至三份是备份记录会写到其它机器上 这些备份记录通常都是采用异步阻塞的方式写 I/O 异步阻塞对网络 I/O 能够提升效率 尤其像上面这种同时写多份相同数据的情况  

  异步非阻塞 

  这种组合方式用起来比较复杂 只有在一些非常复杂的分布式情况下使用 像集群之间的消息同步机制一般用这种 I/O 组合方式 如 Cassandra 的Gossip 通信机制就是采用异步非阻塞的方式 它适合同时要传多份相同的数据到集群中不同的机器 同时数据的传输量虽然不大 但是却非常频繁 这种网络 I/O 用这个方式性能能达到最高  

  虽然异步和非阻塞能够提升 I/O 的性能 但是也会带来一些额外的性能成本 例如会增加线程数量从而增加 CPU 的消耗 同时也会导致程序设计的复杂度上升 如果设计的不合理的话反而会导致性能下降 在实际设计时要根据应用场景综合评估一下

  下面举一些异步和阻塞的操作实例

  在 Cassandra 中要查询数据通常会往多个数据节点发送查询命令 但是要检查每个节点返回数据的完整性 所以需要一个异步查询同步结果的应用场景 部分代码如下

  清单 异步查询同步结果

  class AsyncResult implements IAsyncResult

  private byte[] result_;

  private AtomicBoolean done_ = new AtomicBoolean(false)

  private Lock lock_ = new ReentrantLock()

  private Condition condition_;

  private long startTime_;

  public AsyncResult()

  condition_ = lock_ newCondition() // 创建一个锁

  startTime_ = System currentTimeMillis()

  

  /*** 检查需要的数据是否已经返回 如果没有返回阻塞 */

  public byte[] get()

  lock_ lock()

  try

  if (!done_ get())condition_ await()

  catch (InterruptedException ex)

  throw new AssertionError(ex)

  finallylock_ unlock()

  return result_;

  

  /*** 检查需要的数据是否已经返回 */

  public boolean isDone()return done_ get()

  /*** 检查在指定的时间内需要的数据是否已经返回 如果没有返回抛出超时异常 */

  public byte[] get(long timeout TimeUnit tu) throws TimeoutException

  lock_ lock()

  try            boolean bVal = true;

  try

  if ( !done_ get() )

  long overall_timeout = timeout (System currentTimeMillis() startTime_)

  if(overall_timeout > )// 设置等待超时的时间

  bVal = condition_ await(overall_timeout TimeUnit MILLISECONDS)

  else bVal = false;

  

  catch (InterruptedException ex)

  throw new AssertionError(ex)

  

  if ( !bVal && !done_ get() )// 抛出超时异常

  throw new TimeoutException( Operation timed out )

  

  finallylock_ unlock()      

  return result_;

  

  /*** 该函数拱另外一个线程设置要返回的数据 并唤醒在阻塞的线程 */

  public void result(Message response)

  try

  lock_ lock()

  if ( !done_ get() )

  result_ = response getMessageBody() // 设置返回的数据

  done_ set(true)

  condition_ signal() // 唤醒阻塞的线程

  

  finallylock_ unlock()

  

  

  总结

cha138/Article/program/Java/hx/201311/26096

相关参考

知识大全 Java I/O API之性能分析 (下)

JavaI/OAPI之性能分析(下)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  四注册与处理

知识大全 Java的文件IO机制

Java的文件IO机制  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java有一个庞大的I/O

知识大全 Java I/O流

JavaI/O流  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  面向字节的流类  一预定义的流对

知识大全 Java I/O 包中的Decorator模式介绍

JavaI/O包中的Decorator模式介绍  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!JDK

知识大全 非阻塞I/O简介

Java网络编程从入门到精通(31):非阻塞I/O简介  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧

知识大全 一个非阻塞I/O的例子

Java网络编程从入门到精通(32):一个非阻塞I/O的例子  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看

知识大全 非阻塞I/O的缓冲区(Buffer)

Java网络编程从入门到精通(33):非阻塞I/O的缓冲区(Buffer)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我

知识大全 Java动态代理机制综合分析及扩展

Java动态代理机制综合分析及扩展  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java动态代

知识大全 Java中HashMap的工作机制

Java中HashMap的工作机制  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!    现在很多的

知识大全 Java中的缓冲区

Java中的缓冲区  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  如果将同步I/O方式下的数据传