码迷,mamicode.com
首页 > 其他好文 > 详细

Reactor与NIO

时间:2015-02-15 18:13:44      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:

1. Reactor的由来

Reactor是一种广泛应用在服务器端开发的设计模式。Reactor中文大多译为“反应堆”,我当初接触这个概念的时候,就感觉很厉害,是不是它的原理就跟“核反应”差不多?后来才知道其实没有什么关系,从Reactor的兄弟“Proactor”(多译为前摄器)就能看得出来,这两个词的中文翻译其实都不是太好,不够形象。实际上,Reactor模式又有别名“Dispatcher”或者“Notifier”,我觉得这两个都更加能表明它的本质。

那么,Reactor模式究竟是个什么东西呢?这要从事件驱动的开发方式说起。我们知道,对于应用服务器,一个主要规律就是,CPU的处理速度是要远远快于IO速度的,如果CPU为了IO操作(例如从Socket读取一段数据)而阻塞显然是不划算的。好一点的方法是分为多进程或者线程去进行处理,但是这样会带来一些进程切换的开销,试想一个进程一个数据读500ms,期间进程切换到它3次,但是CPU却什么都不能干,就这么切换走了,是不是也不划算?

这时先驱们找到了事件驱动,或者叫回调的方式,来完成这件事情。这种方式就是,应用业务向一个中间人注册一个回调(event handler),当IO就绪后,这个中间人产生一个事件,并通知handler进行处理。这种回调的方式,也体现了“好莱坞原则”——“Don‘t call us,we‘ll call you”。

好了,我们现在来看Reactor模式。在前面事件驱动的例子里有个问题:我们如何知道IO就绪就个事件,谁来充当这个中间人?Reactor模式的答案是:由一个不断等待和循环的单独进程(线程)来做这件事,它接受所有handler的注册,并负责先操作系统查询IO是否就绪,在就绪后就调用指定handler进行处理,这个角色的名字就叫做Reactor。

2. Reactor与NIO

Java中的NIO可以很好的和Reactor模式结合。关于NIO中的Reactor模式,我想没有什么资料能比Doug Lea大神(不知道Doug Lea?看看JDK集合包和并发包的作者吧)在《Scalable IO in Java》解释的更简洁和全面了。NIO中Reactor的核心是Selector,我写了一个简单的Reactor示例,注意这里有一个核心的Reactor的循环(这种循环结构又叫做EventLoop):

package us.codecraft.netty.reactor;
import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;

public class Handler implements Runnable {
    final SocketChannel socket = null;
    final SelectionKey sk;
    Handler(Selector sel) throws IOException{
        socket.configureBlocking(false);
        sk = socket.register(sel,0);
        sk.attach(this);
        sk.interestOps(SelectionKey.OP_READ);
        sel.wakeup();
    }
    @Override
    public void run(){
        //TODO:处理逻辑
    }
}
package us.codecraft.netty.reactor;
import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;
import java.util.Set;

public class Reactor implements Runnable{
    Selector selector;
    public Reactor() throws IOException {
        selector = Selector.open();
    }
    public void run(){
        try{
            while(!Thread.interrupted()){
                //循环,等待事件
                selector.select();
                Set selected = selector.selectedKeys();
                Interator it = selected.iterator();
                while(it.hasNext())
                    //调用handler,处理事件
                    dispatch((SelectionKey)(it.next()));
                selected.clear();
            }
        }catch(IOException ex){
        }
    }
    void dispatch(SelectionKey k) {
        Runnable r = (Runnable) (k.attachment());
        if(r != null) r.run();
    }
}
package us.codecraft.netty.reactor;
import java.io.IOException;
public class Main{
    public static void main(String[] args) throws IOException {
        Reactor  reactor = new Reactor();
        new Handler(reactor.selector);
        reactor.run();
    }
}


Reactor与NIO

标签:

原文地址:http://my.oschina.net/fhd/blog/378815

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!