BIO、NIO、AIO

BIO-会产生阻塞

 

 

NIO-非阻塞

单线程模型-轮询模式--相当于selector负责client的连接并负责client的读写

package com.xmg.nio;

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;
import java.util.Set;

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.socket().bind(new InetSocketAddress("127.0.0.1", 8888));
        ssc.configureBlocking(false);   //设置非阻塞状态,重要

        System.out.println("server started, listening on :" + ssc.getLocalAddress());
        Selector selector = Selector.open();
        ssc.register(selector, SelectionKey.OP_ACCEPT);   //注册连接请求监听器

        while(true) {
            selector.select();   //这个操作是阻塞方法
            Set<SelectionKey> keys = selector.selectedKeys();  //很多注册监听器,为set类型
            Iterator<SelectionKey> it = keys.iterator();
            while(it.hasNext()) {
                SelectionKey key = it.next();
                it.remove();  //删除掉这个事件,防止下次重复遍历
                handle(key);
            }
        }
    }
    private static void handle(SelectionKey key) {
        if(key.isAcceptable()) {   //客户端请求连接
            try {
                ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                SocketChannel sc = ssc.accept();  //客户端socketchannel建立
                sc.configureBlocking(false);  //设置客户端为非阻塞
                sc.register(key.selector(), SelectionKey.OP_READ );   //注册读监听器
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
        } else if (key.isReadable()) { //flip
            SocketChannel sc = null;
            try {
                sc = (SocketChannel)key.channel();
                ByteBuffer buffer = ByteBuffer.allocate(512);
                buffer.clear();
                int len = sc.read(buffer);  //读取数据
                if(len != -1) {
                    System.out.println(new String(buffer.array(), 0, len));
                }
                ByteBuffer bufferToWrite = ByteBuffer.wrap("HelloClient".getBytes());
                sc.write(bufferToWrite);  //写出数据
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if(sc != null) {
                    try {
                        sc.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

ServerSocketChannel 可读可写,双向通道

设定阻塞为false,configBlocking(false)

selector.select()方法是阻塞的

 

 

ExecutorService pool = Executors.newFixedThreadPool(50);

 

 

new CompletionHandler

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页