一、概述
2010-12-06,JCP投票通过了J2SE 7(JSR336)和J2SE 8(JSR337)两个版本的规范,之前大家比较关注的Lambda表达式和模块化系统则被推迟到了8中。按照Oracle的进度("Plan B"),计划在2011年中推出Oracle JDK7,在2012年晚些时候推出JDK8。截至12月16日,JDK7的所有特性已经完成,也就是说最新的JDK7中已经包括7中所有的特性。
额外提一下此次投票情况,如下。由于Apache与Sun/Oracle关于Java授权的争端最终导致Apache宣布退出JCP。
二、特性列表
下面列出的是J2SE 7规范的参考实现Oracle JDK7的特性列表:
- 虚拟机:支持动态类型语言(InvokeDynamic)
- 语言语法:一些小的改进
-
核心模块:a)、类加载架构设计的升级
b)、添加URLClassLoader的关闭方法
c)、并发和集合的一些更新
-
国际化: a)、Unicode 6.0
b)、Locale enhancement
c)、user locale和 user-interface locale分离
- I/O与网络:a)、新的I/O APIs(NIO.2)
b)、针对zip/jar的NIO.2文件系统提供者
c)、SCTP on Solaris
d)、SDP on Solaris or Linux
e)、使用windows vista IPv6协议栈
f)、支持TLS 1.2
- 安全:支持椭圆曲线加密算法(ECC)
- JDBC:JDBC 4.1和Rowset 1.1
-
客户端:a)、XRender Pipeline
b)、针对jdk 6u10中提供的新功能(半透明和不规则窗体,轻重量级组件的混合使用,改进的AWT警告)创建新的平台接口
c)、Nimbus L2F
d)、JXLayer 组件
- web:更新XML堆栈
三、部分特性详述
1、动态类型语言支持(Invokedynamic)
在JDK中增加了一个invokeDynamic 字节码指令和相关的APIs (JSR 292),用于在缺少静态类型信息的情况下,提高动态语言在Java虚拟机上执行方法调用的性能。
之前,在JVM中存在四种用于方法调用的字节码指令:
Invokevirtual:调用实例方法,基于类的分派。
invokeinterface:调用接口方法
invokestatic:调用一个类的静态方法
invokespecial:调用实例方法。用于特别处理超类方法,私有方法和实例初始化方法的调用。
新的invokedynamic指令在很多方面与invokevirtual类似,但是它更少由字节码的校验规则来约束,而是通过动态类型的检查来保持VM的完整性。
Invokedynamic语法:
对于<method-specification>只需指定方法名称,对描述符的唯一要求是它应引用非空对象。
由于VM只知道方法名称,对于返回类型和参数类型则是未知的,而VM需要链接并调用真实的方法,所以在JDK7中,提供了一套新的动态类型语言的链接机制——方法句柄(Method Handles),VM通过链接机制获取所需真实的方法。链接机制的相关类主要在java.dyn中。
详细内容参见:Da Vinci Machine Project
2、语法上改进
a)、自动化的资源管理-ARM
语法规则:
其中*ResourceDeclarations*必须实现Closeable接口,可以为:
*LocalVariableDeclaration*
*LocalVariableDeclaration* ; *ResourceDeclarations
示例如下图所示,后一个方法为采用ARM的实现。
一些说明:
- JDK7中所有的Closeable对象都实现了AutoCloseable (public interface Closeable extends AutoCloseable)
-
资源实例必须实现AutoCloseable中的public void close()方法才可以
-
JDK7中JDBC 4.1相关接口也会更新为AutoCloseable
-
编译器会在代码块中嵌入变量跟踪异常状态,同时通过一种新的机制来记录隐藏异常
-
可以通过注解处理器来查找适合更新的已有代码 [链接]
b)、泛型示例创建时类型接口的改进—Diamond(<>)
为了使java代码清晰简短,用一个空的类型参数<>,替换之前明确列出的类型参数。例如
替换为:
使用场景:构造对象,委派给变量,传递参数
c)、简化可变参数的方法调用
减少类型安全性的警告信息,把在调用出现时的警告信息放到了方法的声明处
变化前
方法声明:
方法调用:
变化后:
方法声明:
方法调用:
d)、Switch支持字符串
e)、异常的多重捕捉和更加精确的重新抛出
f)、改进的整数值符
3、Fork/Join框架
随着多核技术的发展,为了充分利用硬件资源,需要应用程序在更细的粒度上实现并发控制,为此,Java 7中引入了fork/join并发框架。其采用了分而治之(divide-and-conquer)的思想:
对问题进行评估,确定其大小是否更适合使用顺序解决方案;通常,可通过将问题大小与某个阈值进行比较完成。如果问题大到需要并行分解,算法会递归地将它分成多个子问题,直到每个子问题都足够小,以至于可以高效地串行化解决它们;然后把这些问题放入队列中等待处理(fork步骤),接下来等待所有子问题的结果(join步骤),把多个结果合并到一起。用于选择顺序和并行执行方法的理想阈值是协调并行任务的成本。
伪代码描述如下:
Fork/Join主要类的结构图如下,其中ForkJoinTask的几个子类分别为:
RecursiveAction:无返回结果,不需要进行合并
RecursiveTask:带有返回值
AsyncAction/LinkedAsyncAction: 使用 finish() 方法显式中止
CyclicAction:可使用 TaskBarrier 为每个任务设置不同中止条件
一些说明:
-
Fork/Join框架使用与可用核数相匹配的适当大小的线程池,以减少频繁交换的开销。
-
为避免线程空闲,框架中采用了一种叫工作窃取(work stealing)的技术,可以使空闲线程从一个执行较慢的线程中窃取等待其处理的工作,其主要是通过双端队列(Deque)来实现。
-
Fork/Join框架是针对大的,多核系统采取的并发框架,如果少于4个核心的话,效率并不会有太多的提升。
-
一些额外的新特性,如ThreadLocal伪随机数产生器—ThreadLocalRandom;灵活可复用的同步barrier—Phaser等。
4、新的I/O APIs(NIO.2):
已有I/O接口的问题:
-
需要一个文件系统的接口而不是File类
-
文件名称的处理方式不是跨平台的
-
不支持有效的文件属性访问
-
不支持文件系统的高级特性,如符号链接
-
许多方法只返回true/false或者error而不是有效的异常信息
-
非阻塞I/O机制应用到Socket中,但没有用到文件系统操作中;另外,下一代网络控制器和操作系统会对异步I/O提供更好的支持
NIO.2中的主要功能:
-
支持大量访问文件属性,避免暴露专有API的文件系统接口以及一个实现可拔插的文件系统服务提供者接口
-
在Socket和文件的操作上,支持异步的非阻塞的I/O操作。
-
完成Socket-channel功能(JSR-51),包括附件的对绑定,配置,多播的支持。
基本对象:
FileSystem:文件系统访问接口,是访问文件的对象(Path,WatchService)生成工厂
FileRef:文件(文件或目录)引用
Path:提供独立路径
FileStore:文件存储对象,可能是存储池,设备,分区等
FileSystemProvider:文件系统的服务提供者,是FileSystem,FileRef和FileChanel的创建工厂。
WatchService:监听Watchable对象(Path)的变化和相关事件。
FileVisitor:文件访问者,实现类通过调用Files. walkFileTree来对文件树遍历
PathMatcher:判断给定路径是否符合matcher的模式
UserPrincipalLookupService:提供通过名称来查找用户和组的主体(UserPrincipal),用来判断对文件的访问权限。
主要关系结构图如下:
新旧APIs的对应关系:
java.io.File | java.nio.file |
java.io.File | java.nio.file.Path |
java.io.RandomAccessFile | SeekableByteChannel |
File.canRead, canWrite, canExecute | Path.checkAccess . on Unix, Attributes is used to check the permissions. |
The File methods: isDirectory,isFile, setExecutable, setReadable,setReadOnly, lastModified,setLastModified, length, setWritable | replaced by java.nio.file.attributes package, which reads the attributes in a more efficient bulk operation. |
new File(parent, "newfile") | parent.resolve("newfile") |
File.renameTo | Path.moveTo |
File.delete | Path.delete or Path.delete(boolean) |
File.createNewFile | Path.createFile |
File.deleteOnExit | Specified in the createFile method. |
File.createTempFile | Using the DELETE_ON_CLOSE option with the createFile method. An easy way: Path tmpFile = File.createTempFile("blah",null).toPath(); |
File.exists | Path.exists and Path.notExists |
File.compareTo and equals | Path.compareTo and equals |
File.getAbsolutePath andgetAbsoluteFile | Path.toAbsolutePath |
File.getCanonicalPath andgetCanonicalFile | Path.toRealPath or normalize |
File.toURI | Path.toURI |
File.isHidden | Path.isHidden |
File.list and listFiles | Path.newDirectoryStream |
File.mkdir and mkdirs | Path.createDirectory |
File.listRoots | FileSystem.getRootDirectories |
File.getTotalSpace, File.getFreeSpace,File.getUsableSpace | Attributes.readFileStoreSpaceAttributes |
异步I/O:
异步IO实现的目的主要基于两点:统一Socket和文件系统的异步IO APIs;充分利用操作系统提供的IO机制。
基础类:
-
AsynchronousChannel – 标识一个支持异步I/O的通道。
-
AsynchronousByteChannel – 标识一个支持读写字节的异步通道,这个接口扩展了AsynchronousChannel。
-
AsynchronousDatagramChannel – 标识一个面向数据报套接字异步通道,这个类实现了AsynchronousByteChannel。
-
AsynchronousFileChannel – 标识一个可读,写和操作文件的异步通道,这个类实现了AsynchronousChannel。
-
AsynchronousServerSocketChannel – 标识一个面向流监听套接字的异步通道,这个类实现了AsynchronousChannel。
-
AsynchronousSocketChannel – 标识一个面向流连接套接字的异步通道,这个类实现了AsynchronousByteChannel。
-
AsynchronousChannelGroup – 标识一个用于资源共享的异步通道组。
两种异步操作方式:
Future方式:初始化IO操作,返回java.util.concurrent.Future;在Future接口中定义检测任务是否完成的方法。示例如下:
CallBack方式:调用IO操作时指定CompletionHandler,其在IO操作完成或者失败时调用。
示例如下:
关于异步IO中线程调度及其管理,网上有很多详细的讨论,在此不表。
四、参考资料
1、JaveSE 7 JSR:http://jcp.org/en/jsr/detail?id=336
2、OpenJDK-JDK7:http://openjdk.java.net/projects/jdk7/
3、Mark Reinhold`s Blog:http://blogs.sun.com/mr/
4、Da Vinci Machine Project:http://openjdk.java.net/projects/mlvm/
5、Project Coin: http://openjdk.java.net/projects/coin/
6、Doug Lea:http://gee.cs.oswego.edu/dl/
7、Doug Lea:《A Java Fork/Join Framework》
8、IBM DW: http://www.ibm.com/developerworks/cn/java/j-lo-forkjoin/index.html
9、NIO2 Project: http://openjdk.java.net/projects/nio/
10、Tutorials: http://download.oracle.com/javase/tutorial/essential/io/fileio.html