第一章 简介
先把事实搞清楚,歪曲是以后的事。
——马克·吐温
我们谈谈I/O吧。别走哇,回来!I/O其实没那么枯燥。输入/输出问题(I/O)虽谈不上多吸引人,却很重要。程序员多半把I/O等同于疏通下水管道:无疑很重要,没有不行,但要是直接跟它打交道,就没那么惬意了,搞不好弄得浑身臭哄哄的。本书要讲的可不是管道疏通,但是阅读了随后章节,您就会知道如何让您的数据流动得稍微顺畅一些。
面向对象的程序设计讲的无非就是封装。封装是个好东西:它分解任务,隐藏实施细节,提高对象的重复利用率。这样的分解、整合既适用于程序,也适用于程序员。您没准是一位技艺高超的Java程序员,创建极其复杂的对象,完成惊世骇俗的任务,而对支撑Java平台的基本I/O概念却几乎一无所知。本章,我们暂且把封装问题抛在一边,先来看看某些底层I/O实施细节,希望有助于您更好地组织协调各个零部件的I/O操作。
1.1 I/O与CPU时间的比较
程序员多半当自个儿是软件大师,设计出精巧的例程,这儿压缩几个字节,那儿解开一个循环,要不就在别处作些调整,让对象更加牢固。这些事情当然很重要,乐趣也不少,但是代码优化所带来的回报,可能轻易就被低效的I/O所抵销。I/O操作比在内存中进行数据处理任务所需时间更长,差别要以数量级计。许多程序员一门心思扑在他们的对象如何加工数据上,对影响数据取得和存储的环境问题却不屑一顾。
表1-1所示为对数据单元进行磁盘读写所需时间的假设值。第一列为处理一个数据单元所需平均时间,第二列为对该数据单元进行磁盘读写所需时间,第三列为每秒所能处理的数据单元数,第四列为改变第一第二列的值所能产生的数据吞吐率的提升值。
表1-1. 处理时间与I/O时间对吞吐率的影响比较
|
处理时间(ms)
|
I/O时间(ms)
|
吞吐率(units/sec)
|
增益(%)
|
5
|
100
|
9.52
|
(基准)
|
2.5
|
100
|
9.76
|
2.44
|
1
|
100
|
9.9
|
3.96
|
5
|
90
|
10.53
|
10.53
|
5
|
75
|
12.5
|
31.25
|
5
|
50
|
18.18
|
90.91
|
5
|
20
|
40
|
320
|
5
|
10
|
66.67
|
600
|
前三行显示了处理阶段的效率提升会如何影响吞吐率。把单位处理时间减半,仅能提高吞吐率2.2%。而另一方面,仅仅缩短I/O延迟10%,就可使吞吐率增加9.7%;把I/O时间减半,吞吐率几乎翻番。当您了解到I/O花在一个数据单元上的时间是处理时间的20倍,这样的结果就不足为奇了。
表中所列并非真实数据,目的只在说明相对时间度量,现实情况绝非如此简单。正如您所看到的,影响应用程序执行效率的限定性因素,往往并非处理速率,而是I/O。程序员热衷于调试代码,I/O性能的调试往往被摆在第二位,甚至完全忽略。殊不知,在I/O性能上的小小投入就可换来可观的回报,想来实在令人惋惜。
1.2 CPU已不再是束缚
Java程序员把全部精力用在优化处理效率上,而对I/O关注不足,在某种程度上讲这并非他们的错。在Java的早期,JVM在解释字节码时往往很少或没有运行时优化。这就意味着,Java程序往往拖得很长,其运行速率大大低于本地编译代码,因而对操作系统I/O子系统的要求并不太高。
如今在运行时优化方面,JVM已然前进了一大步。现在JVM运行字节码的速率已经接近本地编译代码,借助动态运行时优化,其表现甚至还有所超越。这就意味着,多数Java应用程序已不再受CPU的束缚(把大量时间用在执行代码上),而更多时候是受I/O的束缚(等待数据传输)。
然而,在大多数情况下,Java应用程序并非真的受着I/O的束缚。操作系统并非不能快速传送数据,让Java有事可做;相反,是JVM自身在I/O方面效率欠佳。操作系统与Java基于流的I/O模型有些不匹配。操作系统要移动的是大块数据(缓冲区),这往往是在硬件直接存储器存取(DMA)的协助下完成的。而JVM的I/O类喜欢操作小块数据——单个字节、几行文本。结果,操作系统送来整缓冲区的数据,java.io的流数据类再花大量时间把它们拆成小块,往往拷贝一个小块就要往返于几层对象。操作系统喜欢整卡车地运来数据,java.io类则喜欢一铲子一铲子地加工数据。有了NIO,就可以轻松地把一卡车数据备份到您能直接使用的地方(ByteBuffer对象)。
这并不是说使用传统的I/O模型无法移动大量数据——当然可以(现在依然可以)。具体地说,RandomAccessFile类在这方面的效率就不低,只要坚持使用基于数组的read( )和write( )方法。这些方法与底层操作系统调用相当接近,尽管必须保留至少一份缓冲区拷贝。
如表1-1所示,如果您的代码大部分时间都处于I/O等待状态,那么,该考虑一下提升I/O效率的问题了,否则,您精心打造的代码多数时间都得闲着。
1.3 进入正题
操作系统研发人员将大量精力投入到提升I/O性能上。众多高手日以继夜地工作,只为完善数据传输技术。操作系统开发商为了取得竞争优势,投入大量时间、金钱,以便在测试数据上胜过竞争对手。
当今的操作系统是现代软件工程的奇迹(没错,有的比奇迹还奇迹),可是Java程序员如何能够既利用操作系统的强大功能,又保持平台独立性?唉,天下没有免费的午餐,此为一例。
JVM是把双刃剑。它提供了统一的操作环境,让Java程序员不用再为操作系统环境的区别而烦恼。与特定平台相关的细枝末节大都被隐藏了起来,因而代码写得又快又容易。但是隐藏操作系统的技术细节也意味着某些个性鲜明、功能强大的特性被挡在了门外。
怎么办呢?如果您是程序员,可以使用Java本地接口(JNI)编写本地代码,直接使用操作系统特性。这样的话,您就被绑定在该操作系统上(也许还是其特定版本上)。如果您的本地代码不是100%无漏洞,您还可能把JVM置于频繁出错乃至崩溃的境地。如果您是操作系统开发商,则可以在您的JVM实现中包含本地代码,以Java API的形式提供这些特性。但这样做可能违反您所签署相关许可协议,根据协议,您只能提供符合一致性要求的JVM。Sun曾就此问题将Microsoft告上法庭,因为很明显,JDirect软件包只能在微软的系统上运行。如果以上方法都行不通,那么您只好转向其他语言,以实现对性能要求极为苛刻的应用。
为了解决这一问题,java.nio软件包提供了新的抽象。具体地说,就是Channel和Selector类。它们提供了使用I/O服务的通用API,JDK 1.4以前的版本是无法使用这些服务的。天下还是没有免费的午餐:您无法使用每一种操作系统的每一种特性,但是这些新类还是提供了强大的新框架,涵盖了当今商业操作系统普遍提供的高效I/O特性。不仅如此,java.nio.channels.spi还提供了新的服务提供接口(SPI),允许接入新型通道和选择器,同时又不违反规范的一致性。
随着NIO的面世,Java已经为严肃的商业、娱乐、科研和学术应用做好了准备。在这些领域,高性能I/O是必不可少的。
除了NIO,JDK 1.4还包含许多其他重要改进。从1.4版开始,Java平台已进入高度成熟期,它仍无法涉足的应用领域已所剩无几。David Flanagan所著《Java技术手册》(第四版)(Java in a Nutshell, Fourth Edition [O'Reilly])是全面了解JDK 1.4各方面特性的绝佳向导。
分享到:
相关推荐
- **第一章:简介** - 1.1 输入输出时间与 CPU 时间 - 1.2 不再受限于 CPU - 1.3 进入主题 - 1.4 I/O 概念 - 介绍了 I/O 基础知识,包括不同类型的 I/O 操作(例如阻塞 I/O 和非阻塞 I/O)、I/O 设备如何与程序...
尽管描述提到的是“accc7.0第一章到第七章部分代码”,但我们的重点将放在Java语言的核心概念以及如何在实际项目中应用它们。这个压缩包可能包含了从基础到进阶的Java编程示例,旨在帮助学习者巩固前七章所学知识,...
本章将覆盖第一种类型的运算,并介绍`Path` API的基本用法。在第四章中,作者将专注于探索第二种类型的操作。本章中介绍的概念将在书中其他部分非常有用。 ### 2. 介绍 Path 类 路径位于文件系统中,文件系统“在...
第一章 简介 .......................................................................................................................... 10 1.1 I/O 与 CPU 时间的比较 .......................................
第一章通常会介绍Java语言的基础概念,包括: 1. **Java的历史与特性**:Java由Sun Microsystems开发,具有跨平台性、面向对象、安全性、健壮性等特征。 2. **Java环境搭建**:讲解如何安装JDK(Java Development ...
在这一章中,我们将介绍Java的历史、特点以及它为何成为如此流行的语言。学习者将学会安装Java开发环境,包括JDK(Java Development Kit)和集成开发环境(IDE),如Eclipse或IntelliJ IDEA。此外,还将讲解Java的...
1. **第一章:Java简介** - Java的历史和发展背景 - Java的主要特点:平台无关性、安全性、健壮性、高性能 - Java的生态环境:JVM(Java虚拟机)、JDK(Java开发工具包) 2. **第二章:Java环境配置** - 下载与...
《Java语言程序设计(进阶篇)》是深入学习Java编程的一本重要教材,其中第21章的课后习题代码集包含了丰富的Java高级特性应用实例,旨在帮助读者巩固和提升在面向对象编程、异常处理、多线程、网络编程、IO流等方面...
第2章,介绍在Socket编程过程中一些基础知识,让大家建立起对这块知识内容的一个整体轮廓; 第3章,结合905.4-2014协议的基本内容,动手实现NIO长连接服务端的实现,以及协议内容的设计和实现思路; 第4章,实现长...
【标题】"第一行代码Java源代码第12章课程代码Java网络编"涉及的是Java编程语言在网络编程方面的知识,这是Java开发中的一个重要领域。在这一章节中,开发者通常会学习如何利用Java API来实现网络通信,包括客户端与...
在本压缩包“chapter25.rar”中,包含的是《Java语言程序设计(进阶篇)》一书的第25章课后习题的源代码。这是一份宝贵的资源,对于正在学习Java编程,尤其是深入阶段的学生来说,是提高编程技能和理解Java高级特性...
学习这一章的内容,对于初学者来说,主要是理解和掌握Java I/O的基本概念、流的分类和使用,以及如何进行文件操作。随着经验的积累,进一步深入学习NIO,可以提升对大规模数据处理和网络通信的理解和应用。
《Java语言程序设计(进阶篇)》是深入学习Java编程的一本教材,其第23章的内容可能涉及了高级Java特性和编程实践。在这个压缩包"chapter23.rar"中,我们很可能会找到与这一章节相关的源代码示例,用于帮助读者理解...
在本实验中,我们将深入探讨Java程序设计的第七章,这一章主要涵盖了Java编程的高级特性和实践应用。实验代码经过测试,确保了其正确性和可用性,这为我们提供了宝贵的实践经验,有助于提升对Java语言的理解。 一、...
1. **Java基础知识**:复习题可能涵盖了Java的基础语法,如变量、数据类型、运算符、控制结构(if-else、switch、for、while等)、方法的定义和调用、类与对象的概念、封装、继承和多态等。答案解析能帮助你快速校验...
其中包含的"Java编程入门第1章测验"部分,旨在帮助学习者检验和巩固他们在学习Java编程第一章节后的理解程度。 在Java编程的初级阶段,理解基础语法和概念至关重要。这包括但不限于: 1. **Java环境搭建**:学习...
1. Java网络编程基础 Java提供了丰富的API来支持网络编程,主要集中在`java.net`包中。基础类如`Socket`和`ServerSocket`用于建立客户端-服务器连接,`URL`和`URLConnection`则用于处理网络资源。 2. Socket编程 `...
本章将深入探讨Java的第14章,这一章节可能涵盖了Java的高级特性,如多线程、集合框架的深入理解、输入/输出流、网络编程以及可能的异常处理和反射机制。 1. **多线程**:Java中的多线程允许程序同时执行多个任务。...
第一章:JAVA简介 本章主要介绍JAVA的历史背景、特点以及其在软件开发中的广泛应用。内容可能包括JAVA的跨平台特性、“一次编写,到处运行”的理念,以及JAVA与其他编程语言的比较。 第二章:JAVA环境搭建 这一章将...