`
jaesonchen
  • 浏览: 313404 次
  • 来自: ...
社区版块
存档分类
最新评论

NIO的写操作分析

 
阅读更多
很多人对NIO的写操作理解的不深,不知道为什么要注册写事件,何时注册写事件,为什么写完之后要取消注册写事件。

Selector.isWriteable()方法监控的是内核的写缓冲器是否可写,所以除非内核的写缓冲区满了,否则一旦一个SocketChannel注册了写事件,每次selector都会选中这个SocketChannel,进入到isWriteable()分支中去。


实际上服务器端写消息时完全可以不注册写事件,直接调用SocketChannel.write(ByteBuffer),也能把数据写到缓冲区并发送出去。但是这种情况下selector不会选择到isWriteable()分支。在写缓冲区满的情况下处理也不灵活,需要while(ByteBuffer.hasRemain())来检查写的状态,会导致CPU空转while.

更好的做法是注册写事件。注册写事件也有两种做法,一种是SocketChannel.register(selector, SelectionKey.OP_WRITE),直接注册到SocketChannel。第二种是用SelectionKey.interestOps(SelectionKey.interestOps() | SelectionKey.OP_WRITE),用SelectionKey来注册。每个SelectionKey只会关联一个SocketChannel,相当于注册到了SocketChannel上。

所以NIO写方法的一般做法是:
1. 注册写事件
2. 写数据
3. 取消注册写事件

注意第3步,每次写完之后要取消注册写事件,SelectionKey.interestOps(SelectionKey.interestOps() & ~SelectionKey.OP_WRITE),否则只要内核写缓冲区可写,这个SocketChannel就会一直被selector选中。

由于有两种注册写事件的方式,所以导致写数据也有两种做法,如果用SocketChannel来注册写事件,那么直接用SocketChannel来写ByteBuffer。
更好的一种做法是第二种,将业务处理和底层Socket操作隔离,采用SelectionKey的Attachment,把业务数据用Attachment的方式和SocketChannel绑定。在SocketChannel注册事件时可以添加Attachment,比如SocketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));

业务方法只需要操作Attachment,往Attachment里面写,然后在Selector.isWriteable()分支里面取出写好的Attachment,然后调用SocketChannel.Write(ByteBuffer) 方法来把数据写到Channel。

大部分的框架都采用第二种方式,比如Thrift的TNonblockingServer处理写事件时,采用一个业务类FrameBuffer来封装业务数据的读写,把FrameBuffer作为Attachment绑定到SocketChannel,并用FrameBuffer记录读写的状态。这样业务功能只需要处理FrameBuffer,
TNonblockingServer来处理SocketChannel实际的写操作。

分享到:
评论

相关推荐

    自己写的Java NIO 同步不阻塞IO操作

    标题"自己写的Java NIO 同步不阻塞IO操作"指的是使用Java NIO库实现的同步但非阻塞的I/O操作。同步意味着程序会一直跟踪操作状态,直到完成;而不阻塞则是指在等待数据时,线程不会被挂起,可以继续执行其他任务。 ...

    Java NIO——Selector机制解析三(源码分析)

    Java NIO,全称为Non-blocking Input/Output,是Java在1.4版本引入的一个新特性,旨在提供一种更高效、更灵活的I/O操作方式。相比于传统的BIO(Blocking I/O),NIO允许我们以非阻塞的方式读写数据,提高了系统资源...

    Java NIO原理 图文分析及代码实现

    ### Java NIO原理 图文分析及代码实现 #### 前言 在深入探讨Java NIO之前,我们先简要回顾一下NIO的概念及其引入的原因。随着互联网的发展,越来越多的应用程序需要处理高并发的网络连接请求。传统的阻塞I/O模型在...

    Java NIO原理分析及代码实例

    NIO的核心在于非阻塞和选择器(Selector),这使得它在处理高并发、低延迟的I/O操作时表现出色。 1. **通道与缓冲区** - **通道(Channel)**:在NIO中,数据的读取和写入是通过通道完成的,它类似于流,但具有...

    高性能网络编程必备技能之IO与NIO阻塞分析

    NIO模型是Java 1.4引入的新特性,它提供了非阻塞的I/O操作。在NIO中,核心组件包括`Selector`、`Channel`和`Buffer`。Selector用于监听多个通道(Channel)的事件,如连接建立、数据读写等,当某个事件发生时,它会...

    Java NIO与IO性能对比分析.pdf

    本文将分析Java NIO与Java IO在性能上的对比,并尝试找出性能差异的原因,以及探讨哪种编程模型更适合高并发的应用场景。 Java IO模型是一种阻塞型I/O模型,在数据的读写过程中,如果线程在等待数据,将会一直被挂...

    Java NIO系列教程(一) Java NIO 概述

    这意味着你可以发起一个读或写操作后立即继续执行其他任务,而不是等待该操作完成。这对于处理大量并发连接的场景特别有用。 - **Buffers**:Buffers提供了数据缓冲区的概念,允许数据在Channel和应用程序之间传输。...

    NIO项目源码.zip

    本项目源码包含了NIO相关的实现,通过分析这些代码,我们可以深入了解NIO的工作原理和实际应用。 1. NIO基础概念 - Channel(通道):NIO的核心组件,它代表了数据传输的路径,如文件、套接字等。通道是双向的,...

    NIO入门pdf分享

    《NIO入门》一书是理解Java NIO(New Input/Output)的重要参考资料,NIO在Java编程中扮演着至关重要的角色,特别是在处理高并发、大数据...结合源码分析和实践应用,能更深入地理解和运用NIO机制,提升Java编程技能。

    nio操作demo

    ### nio操作demo知识点解析 #### 一、项目概述 本示例代码主要展示了如何使用Java NIO(Non-blocking I/O)技术实现一个简单的数据服务器。该服务器通过多个`SelectorLoop`实例处理客户端连接请求,并利用`...

    nio入门文档及示例代码

    NIO提供了非阻塞的I/O操作方式,允许一个线程处理多个输入和输出流,提高了程序在处理并发I/O时的效率。本入门文档及示例代码旨在帮助开发者快速理解并掌握Java NIO的基本概念和用法。 一、NIO基础概念 1. **通道...

    java nio 实现socket

    **传统阻塞I/O模型**:在传统的Java IO编程中,当我们调用`read()`或`write()`方法时,如果当前没有数据可读或写,那么这些方法将会阻塞,直到有数据可用或者写操作完成。这种阻塞机制会导致大量的线程被占用,从而...

    NIO学习系列:核心概念及基本读写

    1. **IDEA插件**:某些IDEA插件,如`JProfiler`,可以显示NIO操作的性能指标,帮助优化代码。 2. **网络抓包工具**:如`Wireshark`,可以观察网络I/O的实际数据传输情况。 3. **内存分析工具**:如`VisualVM`,能...

    NIO处理大文件

    本文将深入探讨如何使用NIO处理大文件,并分析其背后的机制和优势。 1. NIO简介: NIO是Java 1.4引入的新特性,它提供了一种不同于传统IO的I/O操作方式。NIO的核心组件包括通道(Channels)、缓冲区(Buffers)和...

    java NIO技巧及原理

    IO操作是阻塞的,即当一个线程执行读或写操作时,如果数据未准备好,线程会被阻塞,直到数据准备就绪。这种模型在处理少量连接时效率尚可,但面对大量并发连接时,由于每个连接都需要单独的线程,容易造成资源浪费和...

    java_nio.doc

    2. **选择器(Selector)**:选择器是NIO的核心组件,它可以监控多个通道的事件,如连接就绪、数据可读、写操作就绪等。通过注册通道到选择器,并设置感兴趣的事件,可以选择出发生特定事件的通道,从而实现异步I/O...

    Java NIO Ron Hitchens著

    10. **案例分析**:书中可能会通过实际的案例来展示如何使用NIO构建高性能的网络服务器,或者优化文件读写操作。 《Java NIO》这本书对于理解和掌握Java NIO技术至关重要,无论你是Java开发者还是系统架构师,都能...

    java nio入门学习,两个pdf

    2. **文件操作**:NIO提供了高效、灵活的文件读写能力,特别是对于大数据处理,如日志分析、文件复制等。 3. **网络编程**:在网络通信中,NIO可以实现高效的客户端与服务器之间的数据传输,如HTTP、FTP服务器。 4...

    nio.rar_Different_NIO_java nio package

    Java NIO(New IO)是Java 1.4版本引入的一个新特性,它为Java应用程序提供了非阻塞I/O操作的能力,与传统的IO(-blocking I/O)相比,NIO具有更...通过分析和学习这些示例,可以更好地理解和实践Java NIO的各种特性。

Global site tag (gtag.js) - Google Analytics