`

Java NIO Reactor模式

 
阅读更多



 

package com.zzq.nio.reactor;

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

public class Reactor implements Runnable {

    private ServerSocketChannel serverSocketChannel = null;

    private Selector            selector            = null;

    public Reactor() {
        try {
            selector = Selector.open();
            serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.configureBlocking(false);
            serverSocketChannel.socket().bind(new InetSocketAddress(8888));
            SelectionKey selectionKey = serverSocketChannel.register(selector,
                SelectionKey.OP_ACCEPT);
            selectionKey.attach(new Acceptor());
            System.out.println("服务器启动正常!");
        } catch (IOException e) {
            System.out.println("启动服务器时出现异常!");
            e.printStackTrace();
        }
    }

    public void run() {
        while (true) {
            try {
                selector.select();

                Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
                while (iter.hasNext()) {
                    SelectionKey selectionKey = iter.next();
                    dispatch((Runnable) selectionKey.attachment());
                    iter.remove();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void dispatch(Runnable runnable) {
        if (runnable != null) {
            runnable.run();
        }
    }

    public static void main(String[] args) {
        new Thread(new Reactor()).start();
    }

    class Acceptor implements Runnable {
        public void run() {
            try {
                SocketChannel socketChannel = serverSocketChannel.accept();
                if (socketChannel != null) {
                    System.out.println("接收到来自客户端("
                                       + socketChannel.socket().getInetAddress().getHostAddress()
                                       + ")的连接");
                    new Handler(selector, socketChannel);
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

class Handler implements Runnable {

    private static final int READ_STATUS  = 1;

    private static final int WRITE_STATUS = 2;

    private SocketChannel    socketChannel;

    private SelectionKey     selectionKey;

    private int              status       = READ_STATUS;

    public Handler(Selector selector, SocketChannel socketChannel) {
        this.socketChannel = socketChannel;
        try {
            socketChannel.configureBlocking(false);
            selectionKey = socketChannel.register(selector, 0);
            selectionKey.interestOps(SelectionKey.OP_READ);
            selectionKey.attach(this);
            selector.wakeup();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void run() {
        try {
            if (status == READ_STATUS) {
                read();
                selectionKey.interestOps(SelectionKey.OP_WRITE);
                status = WRITE_STATUS;
            } else if (status == WRITE_STATUS) {
                process();
                selectionKey.cancel();
                System.out.println("服务器发送消息成功!");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void read() throws IOException {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        socketChannel.read(buffer);
        System.out.println("接收到来自客户端(" + socketChannel.socket().getInetAddress().getHostAddress()
                           + ")的消息:" + new String(buffer.array()));
    }

    public void process() throws IOException {
        String content = "Hello World!";
        ByteBuffer buffer = ByteBuffer.wrap(content.getBytes());
        socketChannel.write(buffer);
    }
}

 

  • 大小: 45.8 KB
分享到:
评论

相关推荐

    java NIO socket聊天室

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

    Reactor模式和NIO

    Reactor模式和NIO Java的NIO为reactor模式提供了实现的基础机制,它的Selector当发现某个channel有数据时,会通过SlectorKey来告知我们,在此我们实现事件和handler的绑定

    Java NIO原理和使用

    Java NIO非堵塞技术实际是采取Reactor模式,或者说是Observer模式为我们监察I/O端口,如果有内容进来,会自动通知我们,这样,我们就不必开启多个线程死等,从外界看,实现了流畅的I/O读写,不堵塞了。 Java NIO...

    reactor:NIO 编程模型 - Reactor,各版本实现

    依据 Doug Lea 的 基于 NIO 实现的 Reacotr 模式的回显服务器 BasicHandler: 单线程处理器 MultiReactor: 主从 Reactor MultithreadHandler: 线程池处理器 Reactor: 接收连接,I/O 读写 Reactor 模型的说明: ...

    nioreactor:无阻塞IOReact器

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

    bio-nio-aio.zip

    【Java IO】从NIO到Reactor三种模式 博客地址:https://blog.csdn.net/qq_36963950/article/details/107998164

    Java_NIO原理解析

    Java NIO非堵塞技术实际是采取Reactor模式,或者说是Observer(观察员)模式为我们监察I/O端口,如果有内容进来,会自动通知我们,这样,我们就不必 开启多个线程死等,从外界看,实现了流畅的I/O读写,不堵塞了。

    Doug Lea Scalable IO in Java

    Scalable IO in Java -Doug Lea 学习NIO必看经典 描述java nio 和reactor 设计模式之间的关系

    socket-nio-single-reactor.zip

    reactor多线程,java代码demo,帮助理解reactor模式;由于是测试代码,故不保证一定正确,能正常接入传输数据,目前数据包处理没做,故会出现数据截断

    Scalable IO in Java -Doug Lea

    Scalable IO in Java -Doug Lea 描述java nio 和reactor 设计模式之间的关系

    Java NIO:浅析I/O模型

    说起,然后接着阐述了阻塞和非阻塞的区别,接着介绍了阻塞IO和非阻塞IO的区别,然后介绍了同步IO和异步IO的区别,接下来介绍了5种IO模型,后介绍了两种和高性能IO设计相关的设计模式(Reactor和Proactor)。...

    简单了解Java Netty Reactor三种线程模型

    1. Reactor三种线程模型 ...由于Reactor模式使用的是异步非阻塞IO,所有的IO操作都不会导致阻塞,理论上一个线程可以独立处理所有IO相关的操作。从架构层面看,一个NIO线程确实可以完成其承担的职责。例如,通过Ac

    基于事件的NIO多线程服务器

    许多基于NIO的多线程服务器程序往往直接基于选择器(Selector)的Reactor模式实现。这种简单的事件机制对于较复杂的服务器应用,显然缺乏扩展性和可维护性, 而且缺乏直观清晰的结构层次。本文将通过一个基于事件回...

    精通并发与 netty 视频教程(2018)视频教程

    57_Reactor模式透彻理解及其在Netty中的应用 58_Reactor模式与Netty之间的关系详解 59_Acceptor与Dispatcher角色分析 60_Netty的自适应缓冲区分配策略与堆外内存创建方式 61_Reactor模式5大角色彻底分析 62_Reactor...

    Scalable IO in Java by Doug Lea

    Java NIO学习文档。值得学习。reactor 设计模式。作者Doug Lea。java.util.concurrent包的作者

    精通并发与netty视频教程(2018)视频教程

    63_Reactor模式与Netty组件对比及Acceptor组件的作用分析 64_Channel与ChannelPipeline关联关系及模式运用 65_ChannelPipeline创建时机与高级拦截过滤器模式的运用 66_Netty常量池实现及ChannelOption与Attribute...

    disrupted-reactor:Java异步。 IO(基于选择器)+ LMAX Disruptor

    实施的想法: select()的专用线程-React堆模式,通过特殊的WaitStrategy实现为一个中断实例。 N个线程(即处理器)处理IO事件。 一个NIO通道的处理始终在一个线程中进行(这意味着代码不必是线程安全的-&gt;性能提高...

    精通并发与netty 无加密视频

    第63讲:Reactor模式与Netty组件对比及Acceptor组件的作用分析 第64讲:Channel与ChannelPipeline关联关系及模式运用 第65讲:ChannelPipeline创建时机与高级拦截过滤器模式的运用 第66讲:Netty常量池实现及...

    一种基于Netty框架的网络应用服务器设计方法

    Netty是一个异步的事件驱动的网络编程模型框架,使用Java NIO构建了Reactor模型,该模型是一种具有优良扩展性和性能的非阻塞异步模式,它同步等待多个I/O事件的到达,对其进行多路分离,派发给工作线程。Netty包括一...

    高性能IO模型浅析

    (3)IO多路复用(IO Multiplexing):即经典的Reactor设计模式,有时也称为异步阻塞IO,Java中的Selector和Linux中的epoll都是这种模型。 (4)异步IO(Asynchronous IO):即经典的Proactor设计模式,也称为异步非...

Global site tag (gtag.js) - Google Analytics