Java Netty 学习笔记(一)初识Netty
2017-05-20 16:25
288 查看
记得前段时间面试,有些主攻java的公司总会问“你对网络编程比较熟,那java的AIO BIO NIO”知道么,答曰,确实对java不熟。在陈硕muduo中多次提到与netty都是用的
代码:https://github.com/NearXdu/NettyLearn
主线程在loop中阻塞在
具体:
将Socket封装成一个Task,该Task实现Runnable接口,投递到任务队列中,后端的线程池进行处理。线程池中的线程有限,当任务数比较多时,将阻塞在任务队列里面(blocking queue),同样当任务队列为空时,线程池的线程也将挂起。这些java都封装好了,用起来还是很方便的:
使用NIO编程的步骤如下:
成一个循环。需要程序员实现一个CompletionHandler接口,相比同步Selector,AIO是真正的异步调用
例如
one loop per thread,于是找了一个做Java后台的大佬借了一本Netty权威指南,开始学习。
代码:https://github.com/NearXdu/NettyLearn
1. BIO
B阻塞,传统的同步阻塞式IO,在UNP中,这种IO是one connection per thread/process,在Java中似乎Listen Fd 和 Accept Fd 分别有各自的封装
ServerSocket和
Socket.编程框架也是比较简单的:
server = new ServerSocket(port); while (true){ socket = server.accept(); new Thread(new ServerHandler(socket)).start(); } // ServerHandler implements Runnable { private Socket socket; public void run(){ //... } }
主线程在loop中阻塞在
accept调用,当新连接的到来的时候,将connfd扔进handle线程中,主线程继续等待连接.
2.伪异步
不用每次的创建线程,因为这样开销很大,用任务队列+线程池的方式,实现伪异步。具体:
将Socket封装成一个Task,该Task实现Runnable接口,投递到任务队列中,后端的线程池进行处理。线程池中的线程有限,当任务数比较多时,将阻塞在任务队列里面(blocking queue),同样当任务队列为空时,线程池的线程也将挂起。这些java都封装好了,用起来还是很方便的:
executor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), maxPoolSize,//线程池大小 120L, TimeUnit.SECONDS,//最大空闲实现 new ArrayBlockingQueue<java.lang.Runnable>(queueSize));//blocking Queue Size while(true) { socket=server.accept(); executor.execute(new task(socket)); }
3.NIO编程
也就是Reactor,在netty中,有几个重要的组件:Buffer读写缓冲,
Channel对描述符的封装,
Selector多路复用选择器。
使用NIO编程的步骤如下:
//监听套接字 ServerSocketChannel acceptorSvr=ServerSocketChannel.open(); bind; acceptorSvr.configureBlocking(false); //创建selecto并启动线程 Selector selector = Selector.open(); new Thread(new ReactorTask()).start(); //将监听套接字注册到selector上 SelectionKey key=acceptorSvr.register(selector,OP_ACCEPT,ioHandler); //在Reactor线程中轮询 int num=selector.select(); Set selectedKey=selector.selectedKeys(); Iterator it = selectdKey.iterator(); while(it.hasNext()){ SelectionKey key = (SelectionKey)it.next(); //... } //accept新连接 SocketChannel channel= svrChannel.accept(); //为已连接套接字注册IO事件 SelectionKey key=socketChannel.register(selector,SelectionKey.OP_READ,ioHandler)
4.AIO
异步编程,有点类似boost.asio,每次需要注册完成回调,并在完成回调中调用异步操作来驱动,最终形成一个循环。需要程序员实现一个CompletionHandler接口,相比同步Selector,AIO是真正的异步调用
例如
public class AcceptCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, AsyncTimeServerHandler> { @Override public void completed(AsynchronousSocketChannel asynchronousSocketChannel, AsyncTimeServerHandler asyncTimeServerHandler) { asyncTimeServerHandler.asynchronousServerSocketChannel.accept(); ByteBuffer buffer = ByteBuffer.allocate(1024); asynchronousSocketChannel.read(buffer,buffer,new ReadCompletionHandler(asynchronousSocketChannel)); } @Override public void failed(Throwable throwable, AsyncTimeServerHandler asyncTimeServerHandler) { throwable.printStackTrace(); asyncTimeServerHandler.latch.countDown(); } }
相关文章推荐
- 初识Java——(Java学习笔记一)
- Java学习笔记(62)------------线程初识
- Java学习笔记66. 初识多线程
- Apache Mina学习笔记:JavaNIO框架Mina、Netty、Grizzly介绍与对比
- Java学习笔记―第二章 初识Java
- Java学习笔记之NETTY自学路线简析
- Java学习笔记--初识NIO
- Java框架学习笔记——初识Spring之简述
- 初识java——学习笔记
- Java学习笔记--数据库初识
- Java学习笔记:初识Java
- 黑马程序员(学习笔记二)初识java特点
- Java Netty 学习笔记(二)使用Netty编程
- Java GUI学习笔记之初识AWT和Swing
- 学习笔记:java并发编程学习之初识Concurrent
- 初识单例模式(java学习笔记)
- JAVA学习课堂笔记——初识
- java 学习笔记
- 我的Thinking in Java学习笔记(八)
- 我的Thinking in Java学习笔记(六)(zt)