Chapter 1 第1章 缓冲区的使用
学习NIO能更加接近架构级的技术体系,对未来的职业发展有非常好的促进作用。
当你看到以上这段文字的时候,笔者要恭喜你,因为你正在往Java高性能、高并发、高吞吐量技术的道路上迈进,也就代表着未来是有可能将自己的职业规划定位在Java高级程序员、Java资深工程师,以及技术经理、技术总监或首席技术官(CTO)这类职位上。这些职位对Java技术的掌握是有一定要求和标准的,至少笔者认为要将自己对技术的关注点从SSH、SSM分离出去,落脚在多线程、并发处理、NIO及Socket技术上,因为这些技术是开发Java高性能服务器必须要掌握的,甚至有些第三方的优秀框架也在使用这些技术。先不说自己开发框架,即使想要读懂第三方框架的源代码,也要掌握上面提到的多线程、并发处理、NIO及Socket这4种核心技术。当你正在进行SSH、SSM这类Web开发工作时,想要往更高的层次发展,笔者的其他两本书《Java多线程编程核心技术》和《Java并发编程:核心方法与框架》,以及本书一定会带给你非常大的帮助,因为这些内容是Java SE技术中的核心,是衡量一个Java程序员是否合格的明显标志。
在正式开始介绍NIO之前,先简要介绍一下Java SE中的4大核心技术:多线程、并发处理、Socket和NIO。如果你是这些技术的初学者,那么这将帮助你了解这些技术及其用途,以及它们的应用场景。
(1)多线程
可以这样说,高性能的解决方案一定离不开多线程,它可以使1个CPU几乎在同一时间运行更多的任务。在指定的时间单位内运行更多的任务,其实就是大幅度提高运行效率,让软件运行更流畅,处理的数据更多,以提升使用软件时的用户体验。在Java中,使用Thread类来实现多线程功能的处理。在学习多线程时,要注意同步与异步的区别,也就是着重观察synchronized关键字在不同代码结构中的使用效果。另外,多线程的随机性,以及多线程运行乱序的可控制性,这些都是在学习该技术时要着重掌握的。在学习Socket之前,建议先掌握多线程技术,因为使用Socket实现某些功能时是需要借助于多线程的。另外在面试时,多线程方面的知识点是被问及比较多的,可见该技术的重要程度。
推荐笔者的拙作《Java多线程编程核心技术》,封面如图1-1所示。
图1-1 Java多线程编程核心技术
(2)并发处理
你可以愉快地使用Thread类来学习编写多线程的应用程序,但在真实的软件项目开发中实现一些较复杂的逻辑时,其实并不是那么容易,因为多线程的随机性、不方便控制性和调试麻烦等特性也许会给开发过程带来麻烦,但好在Doug Lea开发的java.util.concurrent并发包提供了绝大多数常用的功能。concurrent并发包是对多线程技术的封装,使用并发包中的类可以大幅度降低多线程代码的复杂度。使用封装好的API就可以实现以前使用几十行甚至上百行才能实现的功能。使用并发包可以限制访问的流量、线程间的数据交流,在同步处理时使用更加方便和高效率的锁(Lock)对象、读写锁对象,以及可以提高运行效率的线程池,支持异步及回调接口,支持计划任务,支持fork-join分治编程,而且还提供了并发集合框架。上述功能都是Doug Lea的贡献。只有真正地接触到concurrent并发包,才能深刻地体会使用Thread类编程的原始性,会让你的解题思路更加广阔。
推荐笔者的拙作《Java并发编程:核心方法与框架》,封面如图1-2所示。
图1-2 Java并发编程:核心方法与框架
(3)Socket
高性能服务器的架构设计离不开集群,集群同样离不开Socket。Socket技术可以实现不同计算机间的数据通信,从而实现在集群中的服务器之间进行数据交换,因此,Socket技术是必须要学习的,它也是工作、面试时经常涉及的知识点。即使你是一位Java语言Socket技术的初学者,如果有C++语言学习的经验,那么在学习Socket技术时会觉得得心应手,因为Java语言中的Socket技术其实是封装了操作系统中Socket编程的API,示例代码如下:
JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex0 (JNIEnv *env, jclass cls, jint index) { netif *ifList, *curr; jobject netifObj = NULL; //Retained for now to support IPv4 only stack, java.net.preferIPv4Stack if (ipv6_available()) { return Java_java_net_NetworkInterface_getByIndex0_XP (env, cls, index); } /* get the list of interfaces */ if (enumInterfaces(env, &ifList) < 0) { return NULL; } /* search by index */ curr = ifList; while (curr ! = NULL) { if (index == curr->index) { break; } curr = curr->next; } /* if found create a NetworkInterface */ if (curr ! = NULL) { netifObj = createNetworkInterface(env, curr, -1, NULL); } /* release the interface list */ free_netif(ifList); return netifObj; }
上面的代码片段出自:http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/73a9fef98b93/src/windows/native/java/net/NetworkInterface.c。
从上述代码片段中可以发现,使用Java语言开发Socket软件时,内部调用的还是基于操作系统的Socket的API。
如果没有C++编程经验,就不能学习Java中的Socket技术吗?其实也不是,JDK已经将Socket技术进行了重量级的封装,可以用最简单的代码实现复杂的功能,API接口设计得简洁、有序,因此,即使不懂C++,也能顺利地学习Socket编程。掌握C++语言其实是更有益于学习底层对Socket的封装,研究一些细节问题时会应用到。在常规的学习时,掌握C++语言似乎就没有这么大的帮助了。
Socket技术基于TCP/IP,提前了解一些协议的知识更有利于学习Socket。但是TCP/IP规范非常复杂,我们不可能把该协议的所有细节都掌握,只需要掌握TCP与UDP里常规的内容即可,因为这是Socket技术实现网络通信主要使用的协议。是否有书籍把TCP/UDP的理论知识和Socket编程结合起来?真的有这样的书,推荐《UNIX网络编程(卷1):套接字联网API》和《UNIX网络编程(卷2):进程间通信》。这两本书就将TCP/UDP/Socket进行整合并介绍,对TCP和UDP的细节进行文字讲述,并且使用Socket API进行代码的演示,但是演示的代码使用的是C语言实现的,并不是Java,但Java程序员可以以这两本书作为TCP/UDP理论知识的参考。如果你想更加深入、细致地研究TCP/IP编程,这两本书会提供很大帮助。
Socket编程其实就是实现服务端与客户端的数据通信,不管使用任何的编程语言,在实现上基本上都是4个步骤:①建立连接;②请求连接;③回应数据;④结束连接,这4个步骤的流程图如图1-3所示。
图1-3 Socket编程流程图
虽然图1-3中使用C语言实现Socket编程,但同样可以使用Java中的ServerSocket和Socket类来代替并实现网络通信。本书中Socket的所有案例都是在这4个步骤的生命周期中再结合ServerSocket和Socket类产生的。
另外,本书是将NIO与Socket相结合的,在学习NIO之前,必须先学习Socket,因为NIO中的核心通道类都是基于Socket技术的通道类。学习Socket时要着重学习Socket Option特性,因为它会影响程序运行的效率。在网络程序优化时,除了优化代码之外,还要优化Socket Option中的参数。本书将Socket有关类中的API几乎进行了全部讲解,因为笔者不希望只列举常用代码,而其他知识点一带而过或根本不介绍的情况发生。学习技术时就要以“全面覆盖,某点深钻”的方式进行全方位学习,这样在阅读第三方框架的源代码时才不会出现现查API的情况,极大地提高了代码阅读效率,也会对TCP/IP编程有更深的认识。
(4)NIO
什么是NIO?百度百科中的解释如图1-4所示:
图1-4 百度百科解释的NIO
大致来讲,NIO相比普通的I/O提供了功能更加强大、处理数据更快的解决方案,它可以大大提高I/O(输入/输出)吞吐量,常用在高性能服务器上。随着互联网的发展,在大多数涉及Java高性能的应用软件中,NIO是必不可少的技术之一。
NIO实现高性能处理的原理是使用较少的线程来处理更多的任务,如图1-5所示。
图1-5 NIO高性能的核心原理图
使用较少的Thread线程,通过Selector选择器来执行不同Channel通道中的任务,执行的任务再结合AIO(异步I/O)就能发挥服务器最大的性能,大大提升软件运行效率。
通过对前面4个核心技术的简单介绍,至少你的思维中不再只是Struts、Spring、Hibernate、MyBatis、SpringMVC、CSS、jQuery、AJAX等这些Java Web技术了,而是需要思考如何组织软件架构、服务器分布、通信优化、高性能处理等这些高级技能,为以后的学习和工作打下坚实的技术基础。
学习NIO能更加接近和了解架构级的技术体系,对未来的职业发展有非常好的辅助作用。