Netty知识汇总

本文是Netty知识点的全面汇总,涵盖了Netty的历史、核心组件、原理、使用方法及优缺点,包括阻塞I/O、NIO、Netty的事件循环、线程模型、缓冲区、通道处理器等内容,深入探讨了不同场景下的选择,如NIO和OIO的对比,以及Netty的线程管理和Bootstrap配置。适合Java开发者学习和参考。
摘要由CSDN通过智能技术生成

Netty知识汇总

这篇主要是阅读Netty In Action这本书的一些有关Netty的知识点汇总

历史

阻塞io

一个线程用来处理一个连接,连接的创建和操作连接都是阻塞的
在这里插入图片描述

使用方法
try {
   
	// 监听本地的8000端口
    ServerSocket serverSocket = new ServerSocket(8000);
    // 阻塞等待连接
    Socket clientSocket = serverSocket.accept();
    BufferedReader inputStream = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    PrintWriter writer = new PrintWriter(clientSocket.getOutputStream(), true);
    String request;
    // 阻塞等待输入
    while((request = inputStream.readLine()) != null) {
   
        if ("Done".equals(request)) {
   
            break;
        }
        System.out.println(request);
    }
} catch (IOException e) {
   
    e.printStackTrace();
}
缺点
  1. 同时只能处理一个请求,如果需要处理多个请求,需要创建多个线程
  2. 大量的线程处于等待连接或者等待输入的状态,造成线程资源浪费
  3. 每个线程都的调用栈都需要分配内存,一方面物理机的内存限制了线程数量,另一方面,大量线程之间的线程切换带来大量开销

NIO

NIO使用一个Selector来管理多个Socket,每个Socket注册感兴趣的事件,通过事件通知的方式来确定哪些Socket可以进行处理
因此可以用一个线程来管理多个Socket
NIO有新旧两个版本,旧的版本是在jdk4中引入的,新的版本是在jdk7中引入的
在这里插入图片描述

使用
老的NIO
ServerSocketChannel serverChannel = ServerSocketChannel.open();
ServerSocket ss = serverChannel.socket();
InetSocketAddress address = new InetSocketAddress(8000);
ss.bind(address);
serverChannel.configureBlocking(false);
Selector selector = Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
   
    try {
   
        selector.select();
    } catch (IOException ex) {
   
        ex.printStackTrace();
        // handle in a proper way
        break;
    }
    Set readyKeys = selector.selectedKeys();
    Iterator iterator = readyKeys.iterator();
    while (iterator.hasNext()) {
   
        SelectionKey key = (SelectionKey) iterator.next();
        iterator.remove();
        try {
   
            if (key.isAcceptable()) {
   
                ServerSocketChannel server = (ServerSocketChannel)
                    key.channel();
                SocketChannel client = server.accept();
                System.out.println("Accepted connection from " +
                    client);
                client.configureBlocking(false);
                client.register(selector, SelectionKey.OP_WRITE
                    SelectionKey.OP_READ, ByteBuffer.allocate(100));
            }
            if (key.isReadable()) {
   
                SocketChannel client = (SocketChannel) key.channel();
                ByteBuffer output = (ByteBuffer) key.attachment();
                client.read(output);
            }
            if (key.isWritable()) {
    
                SocketChannel client = (SocketChannel) key.channel();
                ByteBuffer output = (ByteBuffer) key.attachment();
                output.flip();
                client.write(output);
                output.compact();
            }
        } catch (IOException ex) {
   
            key.cancel();
            try {
   
                key.channel().close();
            } catch (IOException cex) {
   
            }
        }
    }
}
新的NIO

在新的NIO中引入了CompletionHandler,当操作完成时,对应的CompletionHandler会被调用
新的NIO相较老的NIO来说,最大的不同是通过使用CompletionHandler来注册回调,不需要检查当前哪些事件准备好了
当事件准备好了,对应的CompletionHandler会自动调用

public void nioTest() throws Exception{
   
    final AsynchronousServerSocketChannel serverChannel =
        AsynchronousServerSocketChannel.open();
    InetSocketAddress address = new InetSocketAddress(8000);
    serverChannel.bind(address);
    final CountDownLatch latch = new CountDownLatch(1);
    serverChannel.accept(null, new
        CompletionHandler<AsynchronousSocketChannel, Object>() {
   
            @Override
            public void completed(final AsynchronousSocketChannel channel,
                Object attachment) {
   serverChannel.accept(null, this);
                ByteBuffer buffer = ByteBuffer.allocate(100);
                channel.read(buffer, buffer,
                    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值