标签:

Reactor 模式简单实现

在网上有部分文章在描述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模式的简单实现:

packagecom.fjn.jdk.nio.reactor.standard;importjava.util.ArrayList;importjava.util.Date;importjava.util.List;importjava.util.Map;importjava.util.concurrent.BlockingQueue;importjava.util.concurrent.ConcurrentHashMap;importjava.util.concurrent.LinkedBlockingQueue;public classStandardReactor {

}classEventDispatcher {

Map eventHandlerMap = new ConcurrentHashMap();

Demultiplexer selector;

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

}public voidregistEventHandler(EventType eventType, EventHandler eventHandler) {

eventHandlerMap.put(eventType, eventHandler);

}public voidremoveEventHandler(EventType eventType) {

eventHandlerMap.remove(eventType);

}public voidhandleEvents() {

dispatch();

}private voiddispatch() {while (true) {

List events =selector.select();for(Event event : events) {

EventHandler eventHandler=eventHandlerMap.get(event.type);

eventHandler.handle(event);

}

}

}

}classDemultiplexer {private BlockingQueue eventQueue = new LinkedBlockingQueue();private Object lock = newObject();

Listselect() {return select(0);

}

List select(longtimeout) {if (timeout > 0) {if(eventQueue.isEmpty()) {synchronized(lock) {if(eventQueue.isEmpty()) {try{

lock.wait(timeout);

}catch(InterruptedException e) {//ignore it

}

}

}

}

}

List events = new ArrayList();

eventQueue.drainTo(events);returnevents;

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

lock.notify();

}

}

}

}classSource {private Date date = newDate();private String id = date.toString() + "_" +System.identityHashCode(date);

@OverridepublicString toString() {returnid;

}

}enumEventType {

ACCEPT, READ, WRITE, TIMEOUT;

}classEvent {publicEventType type;publicSource source;

}abstract classEventHandler {

Source source;public abstract voidhandle(Event event);publicSource getSource() {returnsource;

}

}class AcceptEventHandler extendsEventHandler {privateDemultiplexer selector;publicAcceptEventHandler(Demultiplexer selector) {this.selector =selector;

}

@Overridepublic voidhandle(Event event) {if (event.type ==EventType.ACCEPT) {

Event readEvent= newEvent();

readEvent.source=event.source;

readEvent.type=EventType.READ;

selector.addEvent(readEvent);

}

}

}class ReadEventHandler extendsEventHandler {//private Pipeline pipeline;

@Overridepublic voidhandle(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 extendsEventHandler {

@Overridepublic voidhandle(Event event) {//step 1: encode a message to byte[]//step 2: submit a write task to IOWorker thread pool

}

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

class Acceptor implementsRunnable {private int port; //server socket port

privateDemultiplexer selector;//代表 serversocket

private BlockingQueue sourceQueue = new LinkedBlockingQueue();

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

}public voidaNewConnection(Source source) {

sourceQueue.offer(source);

}public intgetPort() {return this.port;

}public voidrun() {while (true) {

Source source= null;try{//相当于 serversocket.accept()

source =sourceQueue.take();

}catch(InterruptedException e) {//ignore it;

}if (source != null) {

Event acceptEvent= newEvent();

acceptEvent.source=source;

acceptEvent.type=EventType.ACCEPT;

selector.addEvent(acceptEvent);

}

}

}

}classServer {

Demultiplexer selector= newDemultiplexer();

EventDispatcher eventLooper= newEventDispatcher(selector);

Acceptor acceptor;

Server(intport) {

acceptor= newAcceptor(selector, port);

}public voidstart() {

eventLooper.registEventHandler(EventType.ACCEPT,newAcceptEventHandler(selector));new Thread(acceptor, "Acceptor-" +acceptor.getPort()).start();

eventLooper.handleEvents();

}

}

标签:

reactor java实现_Reactor 模式的简单实现相关推荐

  1. JAVA设计模式——工厂模式【简单工厂模式、工厂方法模式、抽象工厂模式】

    目录 简单工厂模式 传统方式 简单工厂模式 静态工厂模式 工厂方法模式 抽象工厂模式 工厂模式JDK-Calendar源码分析 工厂模式小结 简单工厂模式   看一个具体的需求 看一个披萨的项目:要便 ...

  2. java利用解释器模式实现简单计算

    一个利用解释器模式进行的简单计算,只支持+,-,*,/,() 地址:https://gitee.com/hellobb/tools/tree/master/computing

  3. Java设计模式-原型模式

    原型模式   在有些系统中,存在大量相同或相似对象的创建问题,如果用传统的构造函数来创建对象,会比较复杂且耗时耗资源,用原型模式生成对象就很高效. 原型模式的定义与特点   原型(Prototype) ...

  4. java reactor 模式_Reactor模式

    备注: 文章很长,建议收藏起来,慢慢读! 并且,持续更新中- 高薪必备1 : <Netty Zookeeper Redis 高并发实战> 为你打造NIO.Netty 高性能底层原理知识底座 ...

  5. Java的reactor模式_Reactor模式详解+源码实现

    1.Reactor模式介绍 Reactor模式是事件驱动模型,有一个或多个并发输入源,有一个Service Handler,有多个Request Handlers:这个Service Handler会 ...

  6. java简单工厂模式_Java 简单工厂模式

    Java 简单工厂模式 2014-05-28·WeaponX 3717 次浏览 ## 介绍 简单工厂模式又称静态工厂模式. 简单工厂模式由工厂类角色.抽象产品角色和具体产品角色组成. 工厂类角色是本模 ...

  7. Java设计模式-工厂模式(1)简单工厂模式

    Java设计模式-工厂模式(1)简单工厂模式 一.前言 1)例子 2)类图关系 3)代码实现 二.简单工厂模式 2.1.概述: 2.2.类图关系: 2.3.代码修改: 2.4.优缺点 2.5.扩展-简 ...

  8. Java设计模式之(工厂模式)--简单工厂模式--工厂方法模式--抽象工厂模式

    工厂模式: 工厂模式可以分为三类: 1)简单工厂模式(Simple Factory) 2)工厂方法模式(Factory Method) 3)抽象工厂模式(Abstract Factory) 简单工厂模 ...

  9. Java设计模式之 工厂模式(简单工厂模式)

    前一阵子学习了Java 中据说是最简单的设计模式的 单例模式,想一起讨论学习的小伙伴请点击这里: Java 设计模式之单例模式 那么今天就把学习的工厂模式记录下来 工厂模式: 实现了创建者和调用者的分 ...

最新文章

  1. linux存储--从内核文件系统看文件读写过程(四)
  2. Oracle10g中安装Perl环境所产生的冲突
  3. 第七十九期:阿里程序员感慨:码农们过去暴富有多轻松,现在赚钱就有多辛苦
  4. 网络游戏的客户端同步问题 .
  5. 论文浅尝 - ACL2020 | 用于关系三元组抽取的级联二进制标记框架
  6. 搜索 —— 启发式搜索 —— 爬山法
  7. 营口理工学院计算机分数,营口理工学院历年分数线 2021营口理工学院录取分数线...
  8. dell 服务器r410装系统,dell r410安装windows2003系统
  9. 微信小程序常用api
  10. 2022年最强大数据面试宝典(全文50000字)
  11. JS常见的兼容性问题汇总
  12. 《英语语法新思维 基础版1》读书笔记(二)
  13. 曾经,我以为我很懂 MySQL 索引...
  14. 育碧-彩虹六号如何绑定二次验证码/两步验证/身份验证?
  15. Python 中 ‘unicodeescape’ codec can’t decode bytes in position X-X: trun错误
  16. 【MATLAB】在MATLAB中用梯形法求一个表达式在某区间里的积分值
  17. 阿里云免费服务器搭建个人博客
  18. flask框架学习笔记
  19. python 技巧写法
  20. CATIA P3 V5-6R2018 软件下载

热门文章

  1. HDU1716-全排列
  2. R语言使用cox函数构建生存分析回归模型、使用subgroupAnalysis进行亚组分析并可视化森林图
  3. Fcamera产品免责声明
  4. mysql中添加索引的命令_mysql添加索引命令
  5. Metropolis(大都会):以太坊网络的下一个阶段
  6. 二叉堆 | 大根堆 小根堆
  7. python3程序设计答案_Python3程序设计参考答案
  8. 小程序多个输入框输入验证码功能 实现
  9. QVector的内存释放
  10. Tp5 (轮回) 多个富文本应用