Java 杂谈Java并发编程

Java并发——Netty线程模型

2019-06-24  本文已影响59人  Java_苏先生

BIO

1.BIO即阻塞式IO,使用BIO模型,一般会为每个Socket分配一个独立的线程

2.BIO适用于Socket连接不是很多的场景,但现在上百万的连接是很常见的,而创建上百万个线程是不现实的

3.在互联网场景中,连接虽然很多,但每个连接上的请求并不频繁,因此线程大部分时间都在等待IO就绪

理想的线程模型

1.用一个线程来处理多个连接,可以提高线程的利用率,降低所需要的线程

2.使用BIO相关的API是无法实现的,BIO相关的Socket读写操作都是阻塞式的

3.利用NIO相关的API能够实现一个线程处理多个连接,通过Reactor模式实现

Reactor模式

1.Handle指的是IO句柄,在Java网络编程里,本质上是一个网络连接

2.Event Handler是事件处理器,handle_event()处理IO事件,每个Event Handler处理一个IO Handle

  1. Synchronous Event Demultiplexer相当于操作系统提供的IO多路复用API

4.Reactor是Reactor模式的核心

void Reactor::handle_events(){
    // 通过同步事件多路选择器提供的select()方法监听网络事件
    select(handlers);
    // 处理网络事件
    for(h in handlers){
        h.handle_event();
    }
}
// 在主程序中启动事件循环
while (true) {
    handle_events();
}

Netty的线程模型

1.Netty参考了Reactor模式,Netty中最核心的概念是事件循环(EventLoop),即Reactor模式中的Reactor

  1. 在Netty 4.x中,网络连接 : EventLoop : Java线程 = N:1:1

EventLoopGroup

1.EventLoopGroup由一组EventLoop组成

2.Socket处理TCP网络连接请求,是在一个独立的Socket中

3.在Netty中,bossGroup用来处理连接请求的,workerGroup用来处理读写请求的

Echo程序

public class Echo {

    public static void main(String[] args) {
        // 事件处理器
        EchoServerHandler serverHandler = new EchoServerHandler();
        // boss线程组
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        // worker线程组
        EventLoopGroup workerGroup = new NioEventLoopGroup(1);

        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            socketChannel.pipeline().addLast(serverHandler);
                        }
                    });
            // 绑定端口号
            ChannelFuture future = bootstrap.bind(9090).sync();
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 终止worker线程组
            workerGroup.shutdownGracefully();
            // 终止boss线程组
            bossGroup.shutdownGracefully();
        }
    }
}

// Socket连接处理器
class EchoServerHandler extends ChannelInboundHandlerAdapter {

    // 处理读事件
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ctx.write(msg);
    }

    // 处理读完成事件
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    // 处理异常事件
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

写在最后

上一篇 下一篇

猜你喜欢

热点阅读