`
阅读更多
文章转自:http://www.100ksw.com/jsj/java/ggjc/365827.shtml
在网络应用中,一般可以采用同步I/O(阻塞I/O)和非阻塞I/O两种方式进行数据通讯。这两种方式并非互相排斥和互相取代。我们可以在平时的应用中单独采用其中一种通讯方式,也可以混合使用这两种通讯方式。在本文中就什么是非阻塞I/O以及为什么要使用这种通讯方式进行了介绍,在下一篇文章中给出了一个简单的例子来演示在网络应用中如何使用非阻塞I/O进行通讯。
  一、什么是非阻塞I/O
  我们可以将同步I/O称为阻塞I/O,非阻塞I/O称为异步I/O.在本书中采用了比较常用的叫法:同步I/O和非阻塞I/O.虽然它们的叫法不同,但含义是一样的。读者在阅读其他书时应注意这一点。
  在讲解什么是非阻塞I/O之前,首先应了解什么是同步I/O,这里的同步指的是什么。同步这个概念在程序设计中主要是指代码按顺序执行的过程。如在Java程序中的main方法,如果不使用多线程,这个方法中的代码一定是从前往后按顺序执行的。这就叫做同步。如果使用了多线程,从宏观角度来看会有不同的代码段同时执行,这就叫做异步。在同步I/O中的同步概念也类似,也就是说,在I/O通讯过程中,只要是某一步的通讯未结束,就无法进行其他的通讯。那么这里的同步指的是什么呢?要回答这个问题之前,首先让我们先回忆一下,在网络通讯中有哪些地方可能会被阻塞。如果读者看了前面的章节就会知道答案。对于客户端来说,有两个地方可能会被阻塞:连接服务器(调用connect方法时)和读写数据。而在服务端也有两个地方可能会被阻塞:等待客户端请求(调用accept方法时)和读写数据(在一般情况下,写数据不会被阻塞,但如果网络环境比较差的时候,客户端和服务端的写数据操作也可能发生阻塞现象)。也就是说,可以设置超时时间的地方就可能被阻塞。而同步 I/O中的同步就是指除了以下两种情况外程序会一直处于等待状态:
  1. 连接服务器、读写数据或等待客户端请求正常地执行。
  2. 在等待超时时间后,抛出了超时异常。
  在上面我们了解了什么是同步I/O.而非阻塞I/O和同步I/O最明显的不同就是同步I/O所有可能被阻塞的地址在非阻塞I/O中都不会被阻塞。如在读取数据时,如果数据暂时无法被读取。那么在非阻塞I/O中会立刻返回,以便程序可以执行其他的代码,然后系统会不断侦测这个未完成的读取操作,直到可以继续读数据时再来完成这个操作。
  Java在 JDK1.4及以后版本中提供了一套API来专门操作非阻塞I/O,我们可以在java.nio包及其子包中找到相关的类和接口。由于这套API是JDK 新提供的I/O API,因此,也叫New I/O,这就是包名nio的由来。这套API由三个主要的部分组成:缓冲区(Buffers)、通道(Channels)和非阻塞I/O的核心类组成。这三部分的详细内容将在本章的后面介绍。
  二、为什么要使用非阻塞I/O
  在使用同步I/O的网络应用中,如果要同时处理多个客户端请求,或是在客户端要同时和多个服务器进行通讯,就必须使用多线程来处理。也就是说,将每一个客户端请求分配给一个线程来单独处理。这样做虽然可以达到我们的要求,但同时又会带来另外一个问题。由于每创建一个线程,就要为这个线程分配一定的内存空间(也叫工作存储器),而且操作系统本身也对线程的总数有一定的限制。如果客户端的请求过多,服务端程序可能会因为不堪重负而拒绝客户端的请求,甚至服务器可能会因此而瘫痪。
  当然,可以使用线程池(将在第三部分讲解)来缓解服务器的压力,但这并不能解决客户端因访问过于密集而造成的服务器拒绝响应的问题。虽然在服务端还有请求缓冲区作为保障,但这个缓冲区的小是有限的(一般为50),如果客户端的请求数远超过这个数,客户端还是会收到拒绝服务的信息。
  在这种情况下,使用非阻塞I/O就可以解决这个问题。由于使用非阻塞I/O的程序一般是单线程的(有时可能将使用非阻塞I/O的程序段放到一个单独的线程里,而主线程负责处理用户的输入),因此,服务端接收的客户端请求数并不随着工作线程数的增加而增加。所以使用非阻塞I/O模式就不会受到操作系统对线程总数的限制,也不会占用量的服务器资源。
  非阻塞I/O虽然可以到达在处理量客户端请求的同时,又不占用量的服务器资源的目的。但这种通讯方式并不能完全取代同步I/O.如非阻塞I/O并不适合象FTP服务器那样需要保持连接状态的应用(原因将在以后的章节中说明)。非阻塞I/O一般应用在服务端比较多一些,因为客户端一般并不需要处理量的连接(但某些应用除外,如象百度、Google的Web Spider,需要同时下载多个网页,这时就需要在客户端建立量的连接来满足需求),而服务端程序一般需要接收并处理量的客户端请求,因此,就需要使用多线程(使用同步I/O)或非阻塞I/O来达到这个目的。如果某个服务端应用处理的客户端请求没那么多时,使用多线程和同步I/O可能会更好一点,因为这种方式要比非阻塞I/O方式更灵活。
  在前面一直将非阻塞I/O和网络应用放到一起讲。其实非阻塞I/O并不等于网络。我们也可以将非阻塞I/O应用到非网络的应用中,如文件复制。由于同步I /O是基于字节流的,而非阻塞I/O是基于缓冲区和通道的。因此,从理论上,所操作的文件越,非阻塞I/O的优势越能体现出来。而对于比较小的文件操作,这两种方式的效率差不多。根据实验得知,复制一个4G左右的文件,一般情况下,非阻塞I/O方式比同步I/O方式快约15%左右。
另外可看:http://www.ibm.com/developerworks/cn/java/j-javaio/
实例:http://blog.csdn.net/zouxinfox/archive/2007/04/20/1572288.aspx
分享到:
评论
1 楼 fangwei 2010-12-09  
谢谢分享

相关推荐

    线程之舞:JavaScript的单线程与非阻塞I/O揭秘

    ### 线程之舞:JavaScript的单线程与非阻塞I/O揭秘 #### JavaScript简介及主要特点 JavaScript(通常简称为JS)是一种高级、解释型的编程语言,广泛应用于构建交互式的Web应用程序。随着时间的推移,JavaScript已...

    Java 非阻塞I/O使用方法

    Java 非阻塞I/O使用方法 Java 非阻塞I/O是处理高并发的一种手段,在高并发的情况下,创建和回收线程以及在线程间切换的开销变得不容忽视,此时就可以使用非阻塞I/O技术。这种技术的核心思想是每次选取一个准备好的...

    Java网络编程.pdf

    2. **非阻塞I/O示例**:通过使用`Selector`和`Channel`,可以实现基于事件驱动的非阻塞I/O操作,处理大量的并发连接而无需为每个连接创建单独的线程。 3. **缓冲区操作**:在非阻塞I/O中,数据读写通常是通过缓冲区...

    android开发进阶之NIO非阻塞包

    1. **NIO(New I/O)的概念**:NIO是Java 1.4版本开始引入的新I/O处理模型,它通过非阻塞的方式提高了I/O操作的性能。在Android开发中,利用NIO可以显著提升网络通讯的性能,特别是对于需要处理高并发的应用场景。 ...

    java nio 读文件

    NIO的主要特点是面向缓冲区,非阻塞I/O,以及选择器,这些特性使得NIO在处理大量并发连接时表现出更高的效率。在本篇文章中,我们将深入探讨Java NIO如何读取文件。 一、NIO的基本概念 1. 缓冲区(Buffer):NIO的...

    node-v16.18.0-win-x86.zip

    Node.js 由 Ryan Dahl 在2009年创建,它的核心特性是使用了事件驱动、非阻塞I/O模型,这使得Node.js在处理高并发请求时表现出极高的效率。Node.js 使用V8引擎,这是Google Chrome浏览器背后的高性能JavaScript引擎,...

    程序设计训练之 Rust 编程语言 第七讲:I/O 与异步编程

    为了提高效率,Rust提供了异步编程模型来支持非阻塞的I/O操作。 #### Rust 的异步基础 Rust通过一系列的特性来支持异步编程,主要包括: - **异步函数**(`async fn`):允许开发者定义可以异步执行的函数。 - **...

    Verilog HDL非阻塞赋值工程实现

    在Verilog中,非阻塞赋值(Non-blocking Assignment)是编程时的重要概念,尤其在并行处理和时序逻辑描述中起到关键作用。本文将深入探讨非阻塞赋值在实际工程中的应用及其在Quartus II开发环境下的实现。 非阻塞...

    计算机操作系统的基础知识

    I/O模型,如阻塞I/O、非阻塞I/O、I/O多路复用和信号驱动I/O,提供了不同的处理I/O请求的方式。 RAID(冗余磁盘阵列)技术被用于提高数据的可靠性和性能。RAID级别的选择(如RAID 0、RAID 1、RAID 5、RAID 6等)会...

    嵌入式系统培训(系统编程).pptx 操作系统深入理解和编程技巧,动画演示讲稿,附带附件和经典问题

    在嵌入式系统中,I/O处理模型如阻塞I/O和非阻塞I/O对性能和响应时间有显著影响。非阻塞I/O允许程序在等待数据时继续执行其他任务,提高了效率。 总的来说,这篇内容涵盖了嵌入式系统从硬件基础到软件编程的多个方面...

    Java NIO 英文版

    - 探讨I/O概念,如阻塞和非阻塞I/O 2. 缓冲区(Buffers) - 缓冲区的基础知识 - 创建和管理缓冲区 - 字节缓冲区的使用 - 缓冲区的复制 3. 通道(Channels) - 通道的基础知识 - 分散/收集操作 - 文件通道...

    jdk1.5(jdk-1_5_0_08-windows-i586-p.exe)

    虽然NIO.2主要在JDK 7中引入,但JDK 1.5开始引入了初步的NIO支持,包括非阻塞I/O和通道的概念,提高了I/O性能。 JDK 1.5的发布标志着Java语言的重大进步,为后续版本的开发奠定了坚实的基础。这个版本的JDK不仅...

    UNIX系统网络编程.pptx

    - **非阻塞I/O**:与阻塞I/O相反,非阻塞I/O允许进程在等待I/O完成的同时继续执行其他任务。 - **I/O多路复用**:利用`select()`或`poll()`等函数来监控多个文件描述符的状态变化,从而实现对多个I/O操作的高效处理...

    JAVA上课笔记class_13

    NIO(Non-blocking I/O),即非阻塞I/O,是Java为提高I/O操作效率而引入的一种新模型,主要包含在`java.nio`包中。 - **缓冲区(Buffer)**:是NIO的核心概念之一,用于存储数据,具有容量、位置和限制等属性。Buffer...

    Spring Webflux 响应式编程 (二) - WebFlux编程实战

    总结,Spring WebFlux响应式编程模型为开发者提供了全新的Web服务开发方式,通过Reactor库和非阻塞I/O模型,实现了高效、灵活的事件驱动编程。无论是对于新项目的构建还是现有Web MVC应用的升级,WebFlux都值得我们...

    PHP实现非阻塞模式的方法分析

    非阻塞模式允许程序在I/O操作未完成时,可以转而处理其他任务。当I/O操作完成时,再通过某种机制(如事件通知)告知程序继续后续操作。 在PHP中,实现非阻塞模式通常涉及到socket编程,PHP提供了stream_socket_...

    gevent-21.12.0-cp310-cp310-win_amd64.whl.zip

    gevent通过 monkey-patching(猴子补丁)技术,可以透明地替换标准库中的阻塞I/O调用,使其变成非阻塞,从而实现高并发。 **gevent的核心功能:** 1. **协程支持**:gevent 提供了基于greenlet的协程实现,...

    Linux下通过串口收发短信源码

    根据提供的文件信息,本文将详细解析“Linux下通过串口收发短信源码”的核心知识点。...通过对串口通信、非阻塞I/O以及时间管理等方面的理解,可以进一步扩展和优化这个项目,使其适用于更复杂的嵌入式系统应用场景。

    Java网络编程

    非阻塞I/O(Non-blocking I/O)允许程序在等待I/O操作完成时不被阻塞,提高了应用程序的并发能力和效率。 #### 三十一、一个非阻塞I/O的例子 使用Java NIO(New IO)包中的`Selector`、`Channel`和`Buffer`类,...

Global site tag (gtag.js) - Google Analytics