`
ryanflyer
  • 浏览: 102401 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

NIO Reactor模式(阅读NIO笔记)

 
阅读更多

注:内容均节选自附件中的ppt文档。

 

1.网络服务一般的结构:

  读取请求--->解码请求--->处理服务--->编码响应--->发送响应

经典的服务设计是“每一个请求一个线程”,如下图



 2.Reactor模式

Reactor响应I/O事件,分发到合适的Handler处理。

Handler执行非阻塞的动作。

基本的Reactor设计,单线程版本


示例代码:

 

package com.zhang.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Set;

public class Reactor implements Runnable {

    final Selector selector;

    final ServerSocketChannel serverSocketChannel;

    public Reactor(int port) throws IOException {
        selector = Selector.open();
        serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(port));
        serverSocketChannel.configureBlocking(false);
        SelectionKey key = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        key.attach(new Acceptor());
    }

    @Override
    public void run() {
        while (!Thread.interrupted()) {
            try {
                selector.select();
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                for(SelectionKey selectionKey : selectionKeys){
                    dispatch(selectionKey);
                }
                selectionKeys.clear();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

    private void dispatch(SelectionKey selectionKey) {
        Runnable run = (Runnable) selectionKey.attachment();
        if(run != null){
            run.run();
        }
    }
    
    class Acceptor implements Runnable{

        @Override
        public void run() {
            try {
                SocketChannel channel = serverSocketChannel.accept();
                if(channel != null){
                    new Handler(selector,channel);
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }

    }

}
 

 

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;

public class Handler implements Runnable {

    private final static int DEFAULT_SIZE = 8092;

    private final SocketChannel socketChannel;

    private final SelectionKey seletionKey;

    private static final int READING = 0;

    private static final int SENDING = 1;
    
    private int state = READING;

    ByteBuffer inputBuffer = ByteBuffer.allocate(DEFAULT_SIZE);

    ByteBuffer outputBuffer = ByteBuffer.allocate(DEFAULT_SIZE);

    public Handler(Selector selector, SocketChannel channel) throws IOException {
        this.socketChannel = channel;
        socketChannel.configureBlocking(false);
        this.seletionKey = socketChannel.register(selector, 0);
        seletionKey.attach(this);
        seletionKey.interestOps(SelectionKey.OP_READ);
        selector.wakeup();
    }

    @Override
    public void run() {
        if(state == READING){
            read();
        }else if(state == SENDING){
            write();
        }

    }
    
    class Sender implements Runnable {

        @Override
        public void run() {
            try {
                socketChannel.write(outputBuffer);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if(outIsComplete()){
                seletionKey.cancel();
            }
            
            
        }
        
    }

    private void write() {
        try {
            socketChannel.write(outputBuffer);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        while(outIsComplete()){
            seletionKey.cancel();
        }
        
    }

    private void read() {
        try {
            socketChannel.read(inputBuffer);
            if(inputIsComplete()){
                process();
                seletionKey.attach(new Sender());
                seletionKey.interestOps(SelectionKey.OP_WRITE);
                seletionKey.selector().wakeup();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
    }
    
    public boolean inputIsComplete(){
        return false;
    }
    
    public boolean outIsComplete(){
        return false;
        
    }
    
    public void process(){
        
    }

}
 

NIO支持的特性:

 

  • Channels,连接到文件、socket等等,支持非阻塞读。
  • Buffers,与数组相似的对象,能直接从Channels中读写。
  • Selectors,辨识哪一个通道的集合有IO事件。(Tell which of a set of Channels have IO events)
  • SelectionKeys,维护IO事件的状态和绑定。
多线程设计
  • 添加线程增加可扩展性,主要应用在多核处理器中
  • Worker 线程,Reactors要快速出发handlers。handlers的处理降低了Reactor的速度。将非I/O操作分离到其他线程中处理。
  • Multiple Reactor Threads,多Reactor线程。Reactor线程可以使IO操作饱和,分布负载到其他的reactors,负载均衡来匹配CPU和IO之间的速度差异。


 使用多个Reactors


 

 

  • nio.pdf (270.6 KB)
  • 下载次数: 182
  • 大小: 45 KB
  • 大小: 44.6 KB
  • 大小: 101.1 KB
  • 大小: 110.8 KB
分享到:
评论
2 楼 Jnerd 2014-01-20  
Handler初始化的应该注册read,否则select就会阻塞,而因为你的wakeup跑完整个程序。
1 楼 Jnerd 2014-01-20  
运行了不正确呢

相关推荐

    java基于NIO实现Reactor模型源码.zip

    java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现...

    Reactor模式和NIO

    Reactor模式和NIO是两种在网络编程中广泛使用的并发处理技术。Reactor模式是一种事件驱动的设计模式,主要用于解决高并发场景下的系统设计问题,而Java的NIO(Non-blocking Input/Output,非阻塞I/O)是Java平台提供...

    java nio and reactor

    java nio 作者的ppt。 How to Build a Scalable Multiplexed Server With NIO 文中讲述如何使用java nio来实现高性能的服务器。...2、java nio 和 reactor 的映射关系 3、如果使用java nio 来实现高性能服务器

    socket-nio-single-reactor.zip

    本示例代码旨在帮助开发者理解如何使用Java NIO和Reactor模式构建网络服务。尽管测试代码可能不完全准确,但它能展示基本的原理和工作流程。 首先,我们要了解什么是Reactor模式。Reactor模式是一种事件驱动的设计...

    socket通信NIO代理模式demo实例

    本实例"socket通信NIO代理模式demo"将展示如何利用NIO来构建一个高性能的代理服务器。 代理模式是一种设计模式,它允许我们创建一个代理对象来控制对原对象的访问。在NIO代理模式中,代理服务器作为客户端与目标...

    NIO笔记.doc

    Java NIO(New Input/Output)是Java标准库中提供的一种替代传统IO(基于流的I/O)模型的机制,其设计目标是为了提高程序在处理I/O操作时的性能。NIO的核心概念主要包括通道(Channel)、缓冲区(Buffer)和选择器...

    nioreactor:无阻塞IOReact器

    由于React堆线程可以在执行IO时饱和,因此nioreactor使用接受器线程将新连接转发到可以在非阻塞模式下处理读取和写入的React堆池。 建筑分布 要求 2.2.0或以上 Java 8或以上 建立: git clone mvn clean install ...

    ScalableIOJava(NIO如何实现Selector模式的).pdf

    标题《Scalable IO in Java》和描述表明本文档讨论...通过理解Reactor模式以及如何在Java中通过NIO API实现这一模式,开发者可以构建出能够处理大量并发连接的应用程序,并达到高可伸缩性、高可用性以及高性能的目标。

    基于Java NIO反应器模式设计与实现

    反应器设计模式(Reactor Pattern)是事件驱动架构中的一种反应式编程模式,通常用于高并发的场景中。它主要用于处理多个事件的异步分发。在反应器模式中,有一个或多个输入源(例如,连接、数据流)和相应的事件...

    java学习笔记1(java io/nio)

    java学习笔记1(java io/nio)设计模式

    nio demo for nio学习笔记(体系结构以及模块介绍)

    而NIO则采用了非阻塞模式,允许程序在等待数据准备就绪的过程中去做其他事情,提高了程序的效率和并发性。 **NIO的核心组件:** 1. **Channel(通道)**:Channel是数据传输的双向管道,可以同时进行读写操作。例如...

    深入浅出NIO

    3. **Reactor模式**:在NIO中,Reactor模式是一种处理多个客户端连接的并发设计模式。它通过一个线程来监听和接受新的连接,然后分派事件到相应的处理器。相比于传统的多线程模型,Reactor模式可以更有效地管理大量...

    java NIO socket聊天室

    可以作为NIO socket入门的例子,Reactor模式,重点理解key.attach, jar文件里包含了源代码 1,运行server.bat启动服务器,可以打开编辑,修改端口号 2,运行client.bat启动客户端,可以打开编辑,ip,和端口号 3...

    bio-nio-aio.zip

    总结,Java IO的发展经历了从BIO到NIO的转变,再到Reactor模式的优化,每一步都是为了提高系统的并发处理能力和资源利用率。理解并熟练掌握这些IO模型,对于开发高效、稳定的服务器端程序至关重要。通过对压缩包中的...

    nio 服务器/客户端模式

    在NIO服务器/客户端模式中,我们将会探讨如何利用NIO构建高效的通信系统。 首先,让我们了解NIO的基本组件: 1. **通道(Channels)**:通道是数据传输的途径,类似于流。NIO提供多种通道,如SocketChannel、...

    Reactor Pattern (一)

    在Java中,NIO(Non-blocking I/O)框架就是Reactor模式的一个典型应用,它允许一个线程处理多个通道(Channel)上的I/O事件,而不是为每个连接创建一个单独的线程。NIO中的Selector组件就是Reactor的核心,它能够...

    NIO的工作方式

    在NIO的工作流程中,首先会创建一个Selector并打开一个ServerSocketChannel,将其配置为非阻塞模式,然后绑定到指定的端口,并将ServerSocketChannel注册到Selector上,指定监听accept事件。接下来进入循环,通过...

    从Jetty、Tomcat和Mina中提炼NIO构架网络服务器的经典模式

    Jetty、Tomcat和Mina都是Java领域中著名的Web服务器和应用服务器,它们在NIO架构上有着相似的设计模式。本文将从这三个框架中提炼出NIO构架网络服务器的经典模式,并逐一解析它们的核心机制。 首先,Jetty的NIO实现...

    tomcat8.5.56_X64_nio2模式性能优化版+垃圾处理机制.zip

    【标题】:“Tomcat 8.5.56 X64 NIO2模式性能优化版+垃圾处理机制.zip”指的是一个特别针对Windows x64平台优化的Tomcat 8.5.56版本,该版本集成了NIO2(非阻塞I/O)模式,并对垃圾收集(Garbage Collection, GC)...

Global site tag (gtag.js) - Google Analytics