`
bofang
  • 浏览: 126990 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

Java中几种使用NIO的模式

 
阅读更多

 

 

NIO的通用模型是使用一个Selector管理所有的SocketChannel,包括ServerSocketChannel。但是,诸多开源工程中,使用模式会有些不同,下面描述了几种开源软件在某些组件中如何使用Selector的。

 

1. 多个Selector管理客户端的读写

 

Voldemort使用NIO有些不同。ServerSocketChannel是阻塞模式,但是,与客户端通信的SocketChannel却是非阻塞模式。ServerSocketChannel并没有被Selector管理,而是在一个单独的线程中不断监听客户端的请求,建立SocketChannel。

 

一个重要的不同是,Voldemort使用多个Selector来管理SocketChannel,Selector的数量可配置。Voldemort使用round-robin模式来分配某个Selector处理SocketChannel。

 

Voldemort的SelectorManager文档这样写道:

 

First, the thread processing the event calls interestOps() on the SelectionKey to update what types of events it's interested in. In fact, it does this twice - first before any processing occurs it disables all events (so that the same channel isn't selected concurrently (similar to disabling interrupts)) and secondly after processing is completed to re-enable interest in events. Understandably, interestOps() has some internal state that it needs to update, and so the thread must grab a lock on the Selector to do internal interest state modifications. With hundreds/thousands of threads, this lock is very heavily contended as backed up by profiling and empirical testing. 

The second reason the thread pool approach was slow was that after calling interestOps() to re-enable events, the threads in the thread pool had to invoke the Selector API's wakeup() method or else the state change would go unnoticed (it's similar to notifyAll for basic thread synchronization). This causes the select() method to return immediately and process whatever requests are immediately available. However, with so many threads in play, this lead to a near constant spinning of the select()/wakeup() cycling. 

Astonishingly it was found to be about 25% faster to simply execute all IO synchronously/serially as it eliminated the context switching, lock contention, etc. However, we actually have N simultaneous SelectorManager instances in play, which are round-robin-ed by the caller (NioSocketService). 
 

这样做的主要目的是为性能考虑。作者认为,在高频率地调用interestOps, wakeup的情况下,会涉及到Selector加锁,解锁的操作,这些操作会严重影响性能。作者还指出,使用多Selector可以提升大概25%的性能。

 

2. 读写操作由不同的Selector管理

 

Hadoop的RPC组件中的Server使用了这个模式。Listener管理的Selector负责接收链接,数据的读操作。下面是Listener的代码片段:

 

          selector.select();
          Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
          while (iter.hasNext()) {
            key = iter.next();
            iter.remove();
            try {
              if (key.isValid()) {
                if (key.isAcceptable())
                  doAccept(key);
                else if (key.isReadable())
                  doRead(key);
              }
            } catch (IOException e) {
            }
            key = null;
          }
 

一个名为Responder的独立类负责数据的输出操作,该类管理了一个Selector,各个客户端的SocketChannel的写事件会注册到该Selector上。下面是Responder的骨架代码:

 

          waitPending();     // If a channel is being registered, wait.
          writeSelector.select(PURGE_INTERVAL);
          Iterator<SelectionKey> iter = writeSelector.selectedKeys().iterator();
          while (iter.hasNext()) {
            SelectionKey key = iter.next();
            iter.remove();
            try {
              if (key.isValid() && key.isWritable()) {
                  doAsyncWrite(key);
              }
            } catch (IOException e) {
              LOG.info(getName() + ": doAsyncWrite threw exception " + e);
            }
          }

 

这样做的好处很明显,首先降低的了代码复杂度。其次,读写分离,减轻一个Selector带来的锁争用,可以提高性能。 

 

3. Selector只管理ServerSocketChannel打开客户端链接

 

Jetty的NIO Connector使用了这种模式,一个Selector只管理ServerSocketChannel的Accept事件,一旦一个链接被打开,会构造一个SelectableEndPoint,SocketChannel被SelectableEndPoint管理,包括从SocketChannel读数据,以及将数据写到SocketChannel。

 

 

 

 

分享到:
评论

相关推荐

    74个java面试题,只有题目没有答案

    * Java 中有哪几种数据类型?Java 中有基本数据类型(整数、浮点数、字符、布尔值等)和引用数据类型(数组、类、接口等)。 * Java 中什么是继承?继承是指一个类从另一个类继承属性和行为的机制。 * 如何实现继承...

    Java常见面试题208道.docx

    118.在 hibernate 中使用 Integer 和 int 做映射有什么区别? 119.hibernate 是如何工作的? 120.get()和 load()的区别? 121.说一下 hibernate 的缓存机制? 122.hibernate 对象有哪些状态? 123.在 hibernate 中 ...

    JAVA上百实例源码以及开源项目

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    JAVA上百实例源码以及开源项目源代码

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    Java 基础核心总结 +经典算法大全.rar

    关于 null 的几种处理方式大小写敏感 null 是任何引用类型的初始值 null 只是-种特殊的值使用 Null-Safe 方法null 判断 关于思维导图 Java.IO Java.lang Java.math Java.net Java 基础核心总结 V2.0 IO 传统的 ...

    史上最全java面试,103项重点知识,带目录

    15. java 中 IO 流分为几种? 7 16. BIO、NIO、AIO 有什么区别? 7 17. Files的常用方法都有哪些? 8 二、容器 8 18. java 容器都有哪些? 8 19. Collection 和 Collections 有什么区别? 9 20. List、Set、Map 之间...

    高性能IO模型浅析

    服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型。 (2)同步非阻塞IO(Non-blocking IO):默认创建的socket都是阻塞的,非...深入浅出介绍这几种模型

    JAVA3D的网络三维技术的设计与实现.rar

    可以使用Java的Socket或者Java NIO等网络编程技术来实现网络通信,确保客户端和服务器可以相互发送和接收三维场景数据。 场景同步机制:在多用户共享的网络三维场景中,需要设计一种场景同步机制,确保所有用户看到...

    Java服务器端开发面试.doc

    NIO(通道,缓冲区,选择器) Java服务器端开发面试题篇2 thread, start(), run() 多线程里面的关键字,wait, notfiy, 锁(synchronized), lock接口 线程状态,上下文切换,守护线程 消费者和生产者的几种实现方式,...

    Java Tomcat面试题

    Tomcat有哪几种Connector运行模式(优化)? ----------------------------------------- Tomcat有三种Connector运行模式: 1. BIO:同步并阻塞一个线程处理一个请求,缺点是并发量高时,线程数较多,浪费资源。 2...

    安卓java读取网页源码-JavaAyo:java的学习和测试工程,纯java工程,直接运行main方法

    JAVA细粒度锁实现的几种方式: NIO,IO 注解 [笔记] dagger2: Retrofit和ButterKnife的注解怎么实现 反射 JOOR [ClassLoader==&gt;字节码,apk] Socket==&gt;openfire==&gt;netty 设计模式:都在源码里 更好的使用java: [Json...

    Tomcat面试专题及答案.pdf

    tomcat 有哪几种 Connector 运行模式(优化)? bio:传统的 Java I/O 操作,同步且阻塞 IO。 maxThreads=”150”//Tomcat 使用线程来处理接收的每个请求。这个值表示 Tomcat 可创建的最大的线程数。默认值 200。可以...

    服务器Tomcat面试题

    2. Tomcat 有哪几种 Connector 运行模式? Tomcat 有三种 Connector 运行模式: * bio:传统的 Java I/O 操作,同步且阻塞 IO。 * nio:JDK1.4 开始支持,同步阻塞或同步非阻塞 IO。 * aio (nio.2):JDK7 开始支持...

    包含Java面试的各种知识点。过面试有这一个就够了

    有几种?(必会) 1.10 反射(了解) 1.11 jdk1.8 的新特性(高薪常问) 1.12 Java 的异常(必会) 1.13 BIO、NIO、AIO 有什么区别?(高薪常问) 1.14 Threadloal 的原理(高薪常问) 1.16 同步锁、死锁、乐观锁、...

    牛客的代码leetcode代码区别-offer:代码练习

    ConsumerAndProduction:生产者消费者模式的几种Java实现 NiuKe: 牛客网一些题目练习 offer: 2016年4月以来,参加在线笔试的一些公司的编程题目 pattern: 设计模式练习 Practice: 一些无目的的代码练习 base: ...

    javanetty源码-java:jdk、guava、netty等源码阅读

    java netty 源码 项目由一下几个部分组成: ...java.lang.reflect,java动态代理,cglib代理,静态代理,三种代理模式; java集合类; java.util.concurrent; 3.netty: io基础,bio,nio,aio; netty服务端客户端demo;

Global site tag (gtag.js) - Google Analytics