我不生产知识,我只是知识的搬运工。努力通过实践与各位博友交流一些自己的见解。
java nio的相关概念:
Buffer
与channel相连接,从channel中读入和读出数据时都需要缓存,加快数据读取和填充速度。常用的为ByteBuffer,其他的还包括LongBuffer,IntBuffer以及DoubleBuffer等等。一张图示:
Channel
Java NIO channel类似于流,但有一些区别:
1.你可以读和写一个channel。流通常是单向的(读或写)。
2.channel可以异步读写。
3.channel总是读取或写入缓冲区。并将数据从一个缓冲区写入上述通道。
Selector
selector可用于非阻塞I/O操作。selector是监视事件的多个channel的对象。当java nio执行非阻塞IO操作时,selector和带有可选channel的选择键定义了多路IO操作。因此,简单地说,我们可以说selector用于选择准备好进行I/O操作的channel。selector用于监视多个channel中的就绪事件。从而一个selector线程就能处理多个网络连接。
实践代码
上一篇文章java的nio 之 select,poll和epoll理论知识 从操作系统的c语言层面来讲解nio的实现,包括select,poll和epoll他们的区别和使用场景。这篇文章将继续深入探究java 的nio到底层jvm的实现,从而将两者联系起来。先通过时序图有一个总的概括认识:
严格来说,我这个只能算是个草图。哈哈哈,第一次画还请各位多多担待。从源码来看selector实现,windows最终调用的select系统调用,而linux最终调用的epoll系统调用。
从小白看源码的角度来提几点注意事项,大佬勿喷。
1.如果是用windows的idea来追踪源码,那么linux这条线需要自己从openjdk上下载代码来看。
2.关于linux的SelectorProvider的选择,solaris\classes\sun\nio\ch
public static SelectorProvider create() { String osname = AccessController .doPrivileged(new GetPropertyAction("os.name")); if (osname.equals("SunOS")) return createProvider("sun.nio.ch.DevPollSelectorProvider"); if (osname.equals("Linux")) return createProvider("sun.nio.ch.EPollSelectorProvider"); return new sun.nio.ch.PollSelectorProvider(); }View Code
3.如果是追踪到native方法,就需要到openjdk代码中查看c类型的代码,如EpollArrayWrapper中的native int epollWait。solaris\native\sun\nio\ch\EPollArrayWrapper.c
java的类名和c语言的类名是一一对应的。
JNIEXPORT jint JNICALL Java_sun_nio_ch_EPollArrayWrapper_epollWait(JNIEnv *env, jobject this, jlong address, jint numfds, jlong timeout, jint epfd) { struct epoll_event *events = jlong_to_ptr(address); int res; if (timeout <= 0) { /* Indefinite or no wait */ RESTARTABLE(epoll_wait(epfd, events, numfds, timeout), res); } else { /* Bounded wait; bounded restarts */ res = iepoll(epfd, events, numfds, timeout); } if (res < 0) { JNU_ThrowIOExceptionWithLastError(env, "epoll_wait failed"); } return res; }View Code
个人认为有效的学习应该是成系统的,有个人思考和输出的!所以后续还会更新nio实现高效网络框架netty的相关文章。
附上nio的一些基础教程:
https://www.geeksforgeeks.org/introduction-to-java-nio-with-examples/
http://tutorials.jenkov.com/java-nio/index.html