Reactor 模式的简单实现

(一)Reactor模式详解 阅读libevent代码版本为1.4.13 stable版本,阅读书籍参考张亮大神libevent源码深度剖析。 在此主要记录自己学习过程中的一些点点滴滴。 阅读之前需要先了解一下5中I/O模型的比较。 Reactor模式 Reactor(反应堆模式)是libevent的中心思想,常规的I/O多路复用中采用select和poll、epoll等来实现。而Reactor是将上述机制进一步封装,通俗的来讲,就是通过回调机制实现。我们只需将事件的接口注册到Reactor上,当事件发生之后,会回调注册的接口。 Re 阅读详情

在网上有部分文章在描述Netty时,会提到Reactor。这个Reactor到底是什么呢?为了搞清楚Reactor到底是什么鬼,我写了一个简单的Demo,来帮助大家理解他。

 

网上是这么描述Reactor的:

The Reactor design pattern handles service requests that are delivered concurrently to an application by one or more clients.

Each service in an application may consist of serveral methods and is represented by a separate event handler that is responsible for dispatching service-specific requests.

Dispatching of event handlers is performed by an initiation dispatcher, which manages the registered event handlers. Demultiplexing of service requests is performed by a synchronous event demultiplexer.

    大致意思是:Reactor是用于处理多个客户端的请求的设计模式。应用程序提供的每一种服务都可能包括多个方法,并且有必要为这每一个服务分配独立的请求处理器(也可以说是 event handler)。对于Event handler的调度是有Dispatcher来执行的,这个Dispatcher可以管理event handler的注册工作。而分离器Demultiplexer则将一个服务分成了多份。这段话看起来还是不那么容易理解的。

    我对这段话的理解是:应用程序提供多种服务,而每一种服务都会分为多步骤(或者多类别)进行。这里将每一步都作为一个事件,那么每一步的处理就认为是一个event handler。Dispatcher管理这多个步骤的处理器,也即dispatcher管理着多个Event Handler。而将一个服务处理分为多步骤(多个类别)的处理的工作则是有分离器来完成。

 

 

 

 

从这个类图上看,主要有四个角色:

·Handle:事件源。

    ·EventHandler:事件处理器

    ·Dispatcher:调度器。使用Demultiplexer选出可以执行处理的EventHandler,然后执行对EventHandler的调度。

    ·Demultiplexer:同步的事件分离器。

   

 

从类图上看:Dispatcher中有一个Selector和一个EventHandler集合(可以是List,也可以是Map,具体怎么实现根据实际需求)。Regist_handler、remove_handler用于管理EventHandler。

Handle_events用于启动调度,这个方法的实现通常是:使用分离器选择出可以调度的Event,然后对它们进行调度。

 

下面就是对Reactor模式的简单实现:

 

复制代码
package com.fjn.jdk.nio.reactor.standard;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;

public class StandardReactor {

}

class EventDispatcher {
    Map<EventType, EventHandler> eventHandlerMap = new ConcurrentHashMap<EventType, EventHandler>();

    Demultiplexer selector;

    EventDispatcher(Demultiplexer selector) {
        this.selector = selector;
    }

    public void registEventHandler(EventType eventType, EventHandler eventHandler) {
        eventHandlerMap.put(eventType, eventHandler);

    }

    public void removeEventHandler(EventType eventType) {
        eventHandlerMap.remove(eventType);
    }

    public void handleEvents() {
        dispatch();
    }

    private void dispatch() {
        while (true) {
            List<Event> events = selector.select();

            for (Event event : events) {
                EventHandler eventHandler = eventHandlerMap.get(event.type);
                eventHandler.handle(event);
            }
        }
    }
}

class Demultiplexer {
    private BlockingQueue<Event> eventQueue = new LinkedBlockingQueue<Event>();
    private Object lock = new Object();

    List<Event> select() {
        return select(0);
    }

    List<Event> select(long timeout) {
        if (timeout > 0) {
            if (eventQueue.isEmpty()) {
                synchronized (lock) {
                    if (eventQueue.isEmpty()) {
                        try {
                            lock.wait(timeout);
                        } catch (InterruptedException e) {
                            // ignore it
                        }
                    }
                }

            }
        }
        List<Event> events = new ArrayList<Event>();
        eventQueue.drainTo(events);
        return events;
    }

    public void addEvent(Event e) {
        boolean success = eventQueue.offer(e);
        if (success) {
            synchronized (lock) {
                lock.notify();
            }

        }
    }

}

class Source {
    private Date date = new Date();
    private String id = date.toString() + "_" + System.identityHashCode(date);

    @Override
    public String toString() {
        return id;
    }
}

enum EventType {
    ACCEPT, READ, WRITE, TIMEOUT;
}

class Event {
    public EventType type;
    public Source source;
}

abstract class EventHandler {
    Source source;

    public abstract void handle(Event event);

    public Source getSource() {
        return source;
    }
}

class AcceptEventHandler extends EventHandler {

    private Demultiplexer selector;

    public AcceptEventHandler(Demultiplexer selector) {
        this.selector = selector;
    }

    @Override
    public void handle(Event event) {
        if (event.type == EventType.ACCEPT) {

            Event readEvent = new Event();
            readEvent.source = event.source;
            readEvent.type = EventType.READ;

            selector.addEvent(readEvent);
        }
    }

}

class ReadEventHandler extends EventHandler {
    // private Pipeline pipeline;
    
    @Override
    public void handle(Event event) {
        // create channel with a pipeline
        // register the channel to this event dispatcher or a child event dispatcher 

        
        // handle event use the pipeline :
        // step 1:  read to a frame buffer
        // step 2:  use frame decoder to decode buffer as a message (maybe a business object)
        // step 3:  handle the message or submit the message to business thread pool
        // step 4:  register a message event
        
    }
    
} 

class WriteEventHandler extends EventHandler {
    
    @Override
    public void handle(Event event) {
        // step 1: encode a message to byte[]
        // step 2: submit a write task to IOWorker thread pool 
    }
    
}

//-------------------------------分割线--------------------------//


class Acceptor implements Runnable {
    private int port; // server socket port
    private Demultiplexer selector;

    // 代表 serversocket
    private BlockingQueue<Source> sourceQueue = new LinkedBlockingQueue<Source>();

    Acceptor(Demultiplexer selector, int port) {
        this.selector = selector;
        this.port = port;
    }

    public void aNewConnection(Source source) {
        sourceQueue.offer(source);
    }

    public int getPort() {
        return this.port;
    }

    public void run() {
        while (true) {

            Source source = null;
            try {
                // 相当于 serversocket.accept()
                source = sourceQueue.take();
            } catch (InterruptedException e) {
                // ignore it;
            }

            if (source != null) {
                Event acceptEvent = new Event();
                acceptEvent.source = source;
                acceptEvent.type = EventType.ACCEPT;

                selector.addEvent(acceptEvent);
            }

        }
    }

}



class Server {
    Demultiplexer selector = new Demultiplexer();
    EventDispatcher eventLooper = new EventDispatcher(selector);
    Acceptor acceptor;

    Server(int port) {
        acceptor = new Acceptor(selector, port);
    }

    public void start() {
        eventLooper.registEventHandler(EventType.ACCEPT, new AcceptEventHandler(selector));
        new Thread(acceptor, "Acceptor-" + acceptor.getPort()).start();
        eventLooper.handleEvents();
    }

}
Proactor模式&Reactor模式详解 ACE proactor 与 Reactor 模式的详解 立即下载

相关推荐

reactor模式源码

c++高并发模式的reactor模式,其主要作用就是在接收信息之后在线程池中进行选择空闲线程进行处理

Reactor模式详解+源码实现

1.Reactor模式介绍 Reactor模式是事件驱动模型,有一个或多个并发输入源,有一个Service Handler,有多个Request Handlers;这个Service Handler会同步的将输入的请求(Event)多路复用的分发给相应的Request Handler。从结构上,这有点类似生产者消费者模式,即有一个或多个生产者将事件放入一个Queue中,而一个或多个消费者主动的从...

闪电小子 2002

http_server:linux下c语言版基于epoll+reactor模式的http文件下载服务器

一个epoll+reactor的http文件下载服务器 一个线程池的模型

一文搞懂Reactor模型与实现

在网络IOReactor模型和Proactor模型。Reactor基于同步IO模式,Proactor基于异步IO模式。Netty网络框架,Redis等中间件中都有使用到Reactor模型。本文将对Reactor模型的如下三种分类进行学习和实现。单Reactor单线程模型;单Reactor多线程模型;主从Reactor多线程模型。Reactor模型主要就是监听事件分发事件和处理事件。其中Reactor角色会负责监听事件和分发事件Handler角色和Acceptor角色会负责处理事件。Reactor。

Java技术攻略的博客 1万+

STC51单片机串口多字节数据接收的优化策略

本文深入探讨了STC51单片机串口多字节数据接收的优化策略。针对数据丢包、粘包等常见痛点,核心思路是采用“缓冲队列+定时器超时”模式,将实时处理转变为“先收纳,后处理”。文章详细讲解了硬件初始化、中断服务程序优化(快速入队与激活超时裁判)以及主循环的非阻塞设计,并进阶介绍了环形缓冲区实现与错误处理,旨在构建稳定可靠的串口通信系统。

weixin_29264201的博客 373

UE5导入MetaHuman虚拟头像后,连接live link face,面部表情捕捉出错修正

UE5 利用live link face 驱动meta human面部表情捕捉

m0_53122690的博客 6594

使用c++实现简单的reactor模式

reactor是一种高效的服务端模式,实质是使用io多路复用,比如select、epoll、poll等,关于epoll和reactor的详细介绍往上也有很多的博文,这里贴出reactor的一篇博客:reactor模型 reactor模型的几种角色: handle 即文件描述符 Synchronous Event Demultiplexer 即IO多路复用 Event Handler 即处理事件的回调函数 Concrete Event Handler 即具体的实现逻辑处理的函数 Ini

Kmp算法C语言简单实现 4030

从X86到ARM:将VINS-Fusion-GPU和ego-planner迁移到Jetson Orin-NX时,我踩过的那些‘环境差异’坑

本文详细介绍了将VINS-Fusion-GPU和ego-planner从X86平台迁移到Jetson Orin-NX(ARM架构)时遇到的环境差异问题及解决方案。内容涵盖ARM与X86的架构差异、依赖管理、性能调优和硬件接口适配,特别强调了CUDA在ARM平台上的优化配置和内存访问技巧,帮助开发者高效完成跨平台迁移。

weixin_42647395的博客 119

reactor java实现_Reactor 模式的简单实现

标签:Reactor 模式简单实现在网上有部分文章在描述Netty时,会提到Reactor。这个Reactor到底是什么呢?为了搞清楚Reactor到底是什么鬼,我写了一个简单的Demo,来帮助大家理解他。网上是这么描述Reactor的:The Reactor design pattern handles service requests that are delivered concurrent...

weixin_28728279的博客 867

UE5.3与Colosseum配置实战:从编译到问题解决的全流程指南

本文提供了在Windows系统下配置UE5.3与Colosseum仿真环境的全流程实战指南。详细介绍了从软件版本选择、源代码获取、编译脚本执行到解决常见编译错误和引擎崩溃问题的具体步骤,旨在帮助开发者高效搭建无人机、机器人等仿真平台,并顺利运行外部API控制。

weixin_29002595的博客 556

车载以太网:PHY(物理层)介绍

本文以TJA1101芯片为实例介绍了车载以太网PHY(物理层)组成。

kevin1499的博客 6229

事件处理模式之Reactor

本文是上一篇《事件处理模式之Reactor(一)》的下一篇,上一篇主要介绍了reactor模式的基本理论,这一篇主要通过实例,来介绍Reactor模式的具体使用。在开始本文之前,有必要再说明一下,reactor的源码的地址:reactor源码, 感兴趣的读者朋友可以自己用svn客户端check out到本地。 如左图所示为reactor项目的基本结构,整体项目分为三个...

weixin_30855761的博客 265

ReAct框架到多智能体协作:OpenClaw任务分解机制的演进与突破

AI的最终价值是落地,是帮用户解决实际问题,而不是停留在聊天界面里。从ReAct框架到多智能体协作,OpenClaw的任务分解体系走了一条非常务实的路线:所有的优化都是为了解决真实场景里的痛点,所有的设计都是为了让用户用起来更省心。很多人说现在的AI还是“人工智障”,那是因为他们没有用到真正能落地的AI产品。当你用过OpenClaw,体验过你说一句话它就能把一整套复杂任务全都做完的感觉,你就会明白:AI代替人做重复性工作的时代,已经真的来了。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 311

使用c++简单实现reactor模式

事件驱动模型广泛地应用于高性能的web服务器中。而相对应的事件处理模式,最为典型的就是Reactor模式(中文可以称作“反应器” “反应堆”等等,各种叫法都不一样,估且就使用英文吧,叫它Reactor模式)和Proactor模式(中文也称“主动器” “前摄器”,同前者一样称其为Proactor模式)。其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作。 在各种书籍上,能

baidu20008的专栏 1万+

在 Linux 64 位上遭遇 Signal 7 与 ST22 SYSTEM_CORE_DUMPED:从 es/implementation=std 到 /dev/shm 的一套落地排查法

摘要: Linux 64位SAP系统出现SYSTEM_CORE_DUMPED和Signal 7(对应SIGBUS)错误时,核心问题是进程因共享内存资源异常被操作系统强制终止。主要诱因包括:1)/dev/shm的tmpfs默认容量不足(通常仅占物理内存50%);2)SAP内存管理参数es/implementation=map在64位场景下的敏感性。解决方案应双管齐下:在实例profile设置es/implementation=std以降低对tmpfs的依赖,同时按(RAM+Swap)*75%重新配置/dev/

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 163

13、核心网络模块:VyOS 设备配置实战

本文详细介绍了如何使用 Ansible 核心网络模块对 VyOS 虚拟设备进行自动化配置,涵盖环境搭建、变量设置、任务编写、playbook 运行及配置验证全过程。通过实际案例展示了 Ansible 在网络设备管理中的强大功能,包括多设备支持、模板化配置、备份回滚等优势,并提供了最佳实践建议与未来发展趋势分析,帮助读者提升网络运维效率。

linux6sysadmin的博客 114

【muduo库学习】实现最简单的reactor模式

《linux多线程服务端编程 使用muduo c++网络库》的第8章是从0开始讲述一个网络库的实现,比较适合初学者入门。  在本书的第8章中是实现了以下几个类:eventloop类,poller类,channel类 首先分析channel类的定义: #ifndef MUDUO_NET_CHANNEL_H #define MUDUO_NET_CHANNEL_H #include #incl

messiran10的专栏 823

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Reactor模式简单实现与理解

Class Reactor:/** * * 经典的网络服务在每个线程中完成对数据的处理: * 但这种模式在用户负载增加时,性能将下降非常的快。 * 系统运行的性能瓶颈通常在I/O读写,包括对端口和文件的操作上,过去,在打 开一个I/O通道后, * read()将一直等待在端口一边读取字节内容,如果没有内容进来,read()也是傻傻的等, * 这会影响我们程序继续做其他事情,那 么改进

fdsfdf3434的博客 4698

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Reactor模式的.net版本简单实现--DEMO

近期在学习DotNetty,遇到不少的问题。由于dotnetty是次netty的.net版本的实现。导致在网上叙述dotnetty的原理,以及实现技巧方面的东西较少,这还是十分恼人的。在此建议学习和使用Dotnetty的和位小伙伴,真心阅读下netty的相关书籍,如《netty权威指南》。 闲话少说,进入正题。netty的性能之所以能够达到如此的高度。主要由于他使用React...

weixin_30799995的博客 222

网络编程3:基于Reactor模式,简单实现(准)百万并发。

使用结构体:因为结构体是对IO的描述,所以只要有IO被创建,我们就必须创建一个结构体;结构体的id就是创建IO的fd,如果是listen创建的IO,只用设置_accept_callbak,如果是accept创建的IO,需要设置除_accept_callbak外的其他属性。使用数组:添加数据,数组是管理conn的,当创建一个conn,把IO的fd作为索引conn作为value保存在数组中;

weixin_42010295的博客 811

基于NIO使用Reactor模式实现简单的INetty

过一遍有助于更好的理解Netty的运行机制,前提是要对NIO有一定的了解。 https://git.code.tencent.com/lsx0310/inetty.git

qq_39775940的博客 194

java reactor模式例子_回顾 Reactor 模式

Reactor作为网络编程库的核心模式的 Reactor 模式是网络编程中的最常用的模式,反应器 Reactor 又名分派器 Dispatcher, 或通知器 Notifier, 重温一下 POSA2 是对这个模式的描述语境An event-driven application that receives multiple service requests simultaneously, but ...

weixin_42299566的博客 652

Reactor和proactor模式

Reactor模型 转自 https://zhuanlan.zhihu.com/p/137506808 Reactor模式,是指通过一个或多个输入同时传递给服务器的服务请求的事件驱动处理模式。服务端程序处理传入多路请求,并将它们同步分派给请求对应的处理线程。即I/O复用统一监听事件,收到事件后分发给某线程。 Reactor模式中有两个关键组成: (1)Reactor:Reactor在一个单独的线程中运行,负责监听和分发事件,分发给适当的处理程序来对IO事件做出反应,就像公司的电话接线员,它接听来自客户的电话

qq_36553387的博客 2776

nio,一般的reactor,Mina的Reactor

nio:     一个简单的nioserver。启动后,在浏览器输入:http://localhost:1234。就可以看到http的请求。 public class Test implements Callable { private Selector selecto

北蔡的代码世界 2735
上一篇: 《Spring设计思想》AOP实现原理(基于JDK和基于CGLIB)
下一篇: spingMVC模块handlerMapping的初始化过程
还不够
博客等级 码龄16年 113粉丝 24原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值