JAVA的BIO/NIO学习总结
BIO(阻塞IO)
线程阻塞,因此如果没有优化,一个服务端只能为一个客户端服务。
阻塞点:
- 等待连接时 ServerSocket.accept()
- IO操作阻塞 inputStream.read()
多线程IO
业务处理代码交给其他线程单独处理,也就是将IO阻塞放到其他线程中,将is.read()阻塞交给其他线程。
1. 缺点:线程占用太多,一个线程只能处理一个IO事件。线程比较耗资源,因此资源浪费严重,有可能耗尽资源。
伪异步IO
引入java并发包的线程池Executor.newCachedThreadPool()
,使用threadPool.execute(new Runnable())
来交给线程池运行。
线程模型依然没变,一个线程处理一个IO事件。将线程管理交给线程池来管理。
1. 提高了线程的复用。
2. 可以控制线程数。
NIO(非阻塞IO)
Non Blocking IO,基于底层操作系统的epoll模型。线程模型为单线程的Reactor模型。
1. Selector(多路复用器)
2. Channel(ServerSocketChannel(Accept事件),SocketChannel(IO事件))
3. SelectionKey(事件集合)
问题:Selector单线程,复用,使用轮询检查是否有事件到来。然后对到来的事件逐一进行处理,如果一旦事件过大,会导致后续的事件得不到处理。导致新的事件轮询延后。
Netty
- 多线程Reactor
- Boss线程池
- Worker线程池(Handler,MessageReceived,只处理IO事件)
Netty中业务逻辑在哪处理,怎么处理?
高吞吐量,单独开线程、队列处理。
在Worker中处理则会阻塞Worker线程,使其变成单线程。