Java NIO Demo

/*来源: PPT【Scalable IO in Java.pdf】*/

// Reactor:通过分派适当的处理程序来响应IO事件


class Reactor implements Runnable{
    final Selector selector;
    final ServerSocketChannel serverSocket;
    
    Reactor(int port) throws IOException{
        selector = Selector.open();
        serverSocket = ServerSocketChannel.open();
        serverSocket.socket().bind(new InetSocketAddress(port));
        serverSocket.configureBlocking(false);
        SelectionKey sk = serverSocket.register(selector, SelectionKey.OP_ACCEPT);
        sk.attach(new Acceptor());
    }
    
    public void run(){ 
        try{
            while(!Thread.interrupted()){
                selector.select();
                Set selected = selector.selectedKeys();
                Iterator it = selected.iterator();
                while(it.hasNext()){
                    dispatch((SelectionKey)it.next();
                }
                selected.clear();
            }
        }catch(IOException ex){}
    }
    
    void dispatch(SelectionKey k){
        Runnable r = (Runable)(k.attachment());
        if(r != null){
            r.run();
        }
    }
    
    class Acceptor implements Runable{ // inner
        public void run(){
            try{
                SocketChannel c = serverSocket.accept();
                if(c != null){
                    new Handler(selector, c);
                }
            }catch(IOException ex){}
        }
    }
}

final class Handler implements Runable{
    final SocketChannel socket;
    final SelectionKey sk;
    ByteBuffer input = ByteBuffer.allocate(MAXIN);
    ByteBuffer ouput = ByteBuffer.allocate(MAXOUT);
    static final int READING = 0, SENDING = 1;
    int state = READING;
    
    Handler(Selector sel, SocketChannel c) throws IOException{
        socket = c; 
        c.configureBlocking(false);
        // Optionally try first read now
        sk = socket.register(sel, 0); // ** 同一个selector **
        sk.attach(this);
        sk.interestOps(SelectionKey.OP_READ);
        sel.wakeup();
    }
    
    boolean inputIsComplete(){}
    boolean outputIsComplete(){}
    void process(){}
    
    public void run(){
        try{
            if        (state == READING) read();
            else if    (state == SENDING) send();
        }catch(IOException ex){}
    }
    
    void read() throws IOException{
        socket.read(input);
        if(inputIsComplete()){
            process();
            state = SENDING;
            // Normally also do first write now
            sk.interestOps(SelectionKey.OP_WRITE);
        }
    }
    
    void send() throws IOException{
        socket.write(output);
        if(outputIsComplete()){
            sk.cancel();
        }
    }
}
View Code

 

posted @ 2018-04-09 10:36  chenyizh  阅读(114)  评论(0)    收藏  举报