很早就听说tomcat6使用nio了,这几天突然想到一个问题,使用nio代替传统的bio,ThreadLocal岂不是会存在冲突?
首先,何谓nio?
如果读者有socket的编程基础,应该会接触过堵塞socket和非堵塞socket,堵塞socket就是在accept、read、write等IO操作的的时候,如果没有可用符合条件的资源,不马上返回,一直等待直到有资源为止。而非堵塞socket则是在执行select的时候,当没有资源的时候堵塞,当有符合资源的时候,返回一个信号,然后程序就可以执行accept、read、write等操作,这个时候,这些操作是马上完成,并且马上返回。而windows的winsock则有所不同,可以绑定到一个EventHandle里,也可以绑定到一个HWND里,当有资源到达时,发出事件,这时执行的io操作也是马上完成、马上返回的。一般来说,如果使用堵塞socket,通常我们时开一个线程accept socket,当有socket链接的时候,开一个单独的线程处理这个socket;如果使用非堵塞socket,通常是只有一个线程,一开始是select状态,当有信号的时候马上处理,然后继续select状态。
按照大多数人的说法,堵塞socket比非堵塞socket的性能要好。不过也有小部分人并不是这样认为的,例如Indy项目(Delphi一个比较出色的网络包),它就是使用多线程+堵塞socket模式的。另外,堵塞socket比非堵塞socket容易理解,符合一般人的思维,编程相对比较容易。
nio其实也是类似上面的情况。在JDK1.4,sun公司大范围提升Java的性能,其中NIO就是其中一项。Java的IO操作集中在java.io这个包中,是基于流的阻塞API(即BIO,Block IO)。对于大多数应用来说,这样的API使用很方便,然而,一些对性能要求较高的应用,尤其是服务端应用,往往需要一个更为有效的方式来处理IO。从JDK 1.4起,NIO API作为一个基于缓冲区,并能提供非阻塞O操作的API(即NIO,non-blocking IO)被引入。
BIO与NIO一个比较重要的不同,是我们使用BIO的时候往往会引入多线程,每个连接一个单独的线程;而NIO则是使用单线程或者只使用少量的多线程,每个连接共用一个线程。
这个时候,问题就出来了:我们非常多的java应用是使用ThreadLocal的,例如JSF的FaceContext、Hibernate的session管理、Struts2的Context的管理等等,几乎所有框架都或多或少地应用ThreadLocal。如果存在冲突,那岂不惊天动地?
后来终于在Tomcat6的文档(http://tomcat.apache.org/tomcat-6.0-doc/aio.html)找到答案。根据上面说明,应该Tomcat6应用nio只是用在处理发送、接收信息的时候用到,也就是说,tomcat6还是传统的多线程Servlet,我画了下面两个图来列出区别:
tomcat5:客户端连接到达 -> 传统的SeverSocket.accept接收连接 -> 从线程池取出一个线程 -> 在该线程读取文本并且解析HTTP协议 -> 在该线程生成ServletRequest、ServletResponse,取出请求的Servlet -> 在该线程执行这个Servlet -> 在该线程把ServletResponse的内容发送到客户端连接 -> 关闭连接。
我以前理解的使用nio后的tomcat6:客户端连接到达 -> nio接收连接 -> nio使用轮询方式读取文本并且解析HTTP协议(单线程) -> 生成ServletRequest、ServletResponse,取出请求的Servlet -> 直接在本线程执行这个Servlet -> 把ServletResponse的内容发送到客户端连接 -> 关闭连接。
实际的tomcat6:客户端连接到达 -> nio接收连接 -> nio使用轮询方式读取文本并且解析HTTP协议(单线程) -> 生成ServletRequest、ServletResponse,取出请求的Servlet -> 从线程池取出线程,并在该线程执行这个Servlet -> 把ServletResponse的内容发送到客户端连接 -> 关闭连接。
从上图可以看出,BIO与NIO的不同,也导致进入客户端处理线程的时刻有所不同:tomcat5在接受连接后马上进入客户端线程,在客户端线程里解析HTTP协议,而tomcat6则是解析完HTTP协议后才进入多线程,另外,tomcat6也比5早脱离客户端线程的环境。
实际的tomcat6与我之前猜想的差别主要集中在如何处理servlet的问题上。实际上即使抛开ThreadLocal的问题,我之前理解tomcat6只使用一个线程处理的想法其实是行不同的。大家都有经验:servlet是基于BIO的,执行期间会存在堵塞的,例如读取文件、数据库操作等等。tomcat6使用了nio,但不可能要求servlet里面要使用nio,而一旦存在堵塞,效率自然会锐降。
分享到:
相关推荐
Java NIO(New Input/Output)是Java标准库中提供的一种I/O模型,与传统的 Blocking I/O(同步阻塞I/O)相对。NIO在Java 1.4版本引入,其设计目标是提供一种更高效、更灵活的I/O操作方式,特别适合处理大量并发连接...
总的来说,Java NIO与零拷贝技术的结合,为开发者提供了更高效率、更低资源消耗的I/O处理手段,尤其在处理大数据和高并发场景时,其优势更为明显。理解并掌握这些知识,对于提升Java应用程序的性能至关重要。
本教程将深入讲解如何使用Java NIO实现非阻塞服务端与客户端的通信。 1. **Java NIO基础** - **通道(Channels)**:NIO中的通道类似于传统IO的流,但它们可以同时读写,并且支持非阻塞操作。 - **缓冲区...
本资料"JavaNIO服务器实例Java开发Java经验技巧共6页"可能是某个Java开发者或讲师分享的一份关于如何在Java中构建NIO服务器的教程,涵盖了6个关键页面的内容。尽管具体的细节无法在此直接提供,但我们可以根据Java ...
本文将着重探讨电信业务应用软件的发展历程和技术变迁,特别是Java NIO框架在这一过程中所扮演的重要角色。 **1.2 华为电信软件的技术演进史** ##### 1.2.1 C和C++主导的第一代架构 在2005年以前,华为电信软件的...
总结起来,Java NIO在Tomcat中的应用显著提升了服务器的并发处理能力,减少了线程上下文切换的开销,使得Tomcat能够更高效地服务于高并发的Web应用。对于大型互联网服务和企业级应用来说,选择使用NIO模式的Tomcat是...
【标题】:“手写 Tomcat NIO” 在深入探讨手写Tomcat NIO之前,我们首先需要理解NIO(Non-...在实际项目中,如果需要高性能的Web服务器,可能需要考虑使用成熟的开源产品,如Tomcat本身或Netty等高性能NIO框架。
例如,Tomcat、Netty等高性能服务器框架就广泛使用了Java NIO技术。 本压缩包中的"java-instantcode-developing-applications-using-java-nio.17016.chm"文件很可能是详细讲解如何使用Java NIO进行应用开发的电子书...
Java NIO,全称为Non-Blocking Input/Output,是Java平台中用于替代标准I/O(BIO)模型的一种新机制。在Java 1.4版本引入NIO后,它为高性能、并发处理提供了更为强大的支持,尤其适用于网络编程和大数据处理场景。 ...
在实际应用中,Java NIO常用于以下场景: - **高并发网络服务**:例如,基于NIO实现的服务器可以同时处理成千上万个连接,如Tomcat、Netty等高性能网络框架就是基于NIO构建的。 - **大文件读写**:NIO的缓冲区机制...
Java NIO 通信框架在电信领域的实践涉及到Java技术在电信软件开发中的演进历程,从C和C++主导的时代到Java的广泛应用。在早期,由于Java的多线程能力和非阻塞I/O支持不足,以及缺乏相关的开源框架,C/C++在高性能、...
Jetty、Tomcat和Mina都是Java领域中著名的Web服务器和应用服务器,它们在NIO架构上有着相似的设计模式。本文将从这三个框架中提炼出NIO构架网络服务器的经典模式,并逐一解析它们的核心机制。 首先,Jetty的NIO实现...
### 使用Java NIO编写高性能服务器的关键知识点 #### 一、NIO概述 - **NIO简介**:NIO(New IO)自JDK 1.4引入以来,为Java提供了非阻塞IO的支持,这对于提高服务端应用的性能至关重要。NIO的核心特性包括缓冲区...
- **MVC模式**:讨论了在Java Web中使用Servlet和JSP实现Model-View-Controller(MVC)设计模式的方法。 3. **Java Web项目结构** - **Web应用目录结构**:讲解了标准的Java Web项目目录结构,如WEB-INF目录下的...
在实际项目中,NIO常用于高并发的网络服务器,例如Tomcat、Netty等框架就大量使用了NIO技术。此外,对于大数据处理、文件操作等场景,NIO也能提供更好的性能优化。 在编程实践过程中,要注意NIO虽然提高了并发能力...
【标题】"Tomcat-9-Java" 是一个与Java应用程序服务器相关的主题,特别是关于Tomcat的第9个主要版本。Tomcat是一个开源的、基于Java的Web应用服务器,广泛用于部署Servlet和JSP应用程序。它由Apache软件基金会维护,...
【标题】"tomcat6到8windows版本.zip" ...对于Windows用户,选择适合的Tomcat版本取决于应用程序的需求和所使用的Java版本。同时,64位版本的Tomcat能够处理更大的内存分配,适合运行大型或资源密集型的Web应用程序。
Java NIO(New Input/Output)是Java标准库中的一部分,自Java 1.4版本引入,用于替代传统的IO API。NIO提供了更高效、非阻塞的数据输入和输出方式,特别适合处理大量并发连接的场景,如网络服务器。本教程将深入...
【标题】:“Tomcat版本6、7、8”的对比与演变 在Java Web开发领域,Apache Tomcat是一款广泛应用的开源Servlet容器,它实现了Java Servlet和JavaServer Pages(JSP)技术规范。Tomcat6、Tomcat7和Tomcat8是三个...
2. **NIO.2支持**:Tomcat8采用了Java NIO.2(New I/O 2)模型,相较于传统的BIO( Blocking I/O)和NIO,NIO.2提供了更好的异步I/O处理能力,能处理更多的并发连接,提高了服务器的性能和响应速度。 3. **改进的...