在Java 7中可能引入AIO,进一步优化Java处理I/O的性能。AIO全称是asynchronous i/o,有时也叫new i/o 2。可以参考下面网站查看详细的规范:
http://openjdk.java.net/projects/nio/
其实,梳理java里的i/o操作,经历了几个阶段:最原始的i/o,以java.io.*包为代表,第二阶段,在jdk1.4里面引入了nio(non-blocking i/o),这个主要以java.nio.*包为代表,后来java.io.*里的一些类也基于nio重新实现了。第三个阶段,就是aio。
对于aio,http://openjdk.java.net/projects/nio/presentations/TS-4222.pdf这个是个很好的介绍文章。aio和nio最大的区别是真正做到完全意义上的异步,事件驱动,而nio某种程度上还是同步实现。
"With non-blocking I/O, you're getting events through a selector when the channel is ready to do I/O. The asynchronous API gives you a notification when the I/O is completed.
For example, with a socket channel in a non-blocking mode, you register with a selector, and the selector will give you a notification when there is data on that socket to read. With the asynchronous I/O, you actually start the read, and the I/O will complete sometime later when the read has happened and there is data in your buffer.
In the asynchronous API we have what we call a completion handler. You specify a completion handler when you do your read, and the completion handler is invoked to tell you that the I/O operation has completed.
We put a lot of thought into how the asynchronous API would be used in server applications. You'll see in the asynchronous I/O package that we allow high-end servers to be able to plug in their own thread pools, have their own configuration of thread pools, and so on. "
non-blocking i/o是在jsr51中提出的,是基于reactor模式的.
aio包括在jsr203中,是基于proactor的.
http://www.artima.com/lejava/articles/more_new_io.html
因为aio在java 7里面才会正式引入,那目前我们大部分时间还是在用nio,下面这个教程非常不错:
https://www.ibm.com/developerworks/java/tutorials/j-nio/,介绍了所有nio的新功能。最直观的比较就是同样功能的新旧实现对比,比如说完成一个简单的文件复制功能。
原始的i/o实现类似于:
String infile = args[0]; String outfile = args[1]; Reader rr = new BufferedReader(new FileReader(infile)); Writer w = new BufferedWriter(new FileWriter(outfile)); while (true) { char[] buf = new char[4 * 1024]; int r = rr.read(buf); if (r == -1) { break; } w.write(buf); } w.flush(); rr.close(); w.close();
而使用nio后,实现如下:
String infile = args[0]; String outfile = args[1]; FileInputStream fin = new FileInputStream(infile); FileOutputStream fout = new FileOutputStream(outfile); FileChannel fcin = fin.getChannel(); FileChannel fcout = fout.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024); while (true) { buffer.clear(); int r = fcin.read(buffer); if (r == -1) { break; } buffer.flip(); fcout.write(buffer); }
做一个简单的测试,会发现性能确实有很大地提高,当然在nio里面还提供了很多高级功能,比如direct buffer和memory-mapped file,他们的性能就更好了。
上面的代码用direct buffer实现就是:
String infile = args[0]; String outfile = args[1]; long begin = System.currentTimeMillis(); FileInputStream fin = new FileInputStream( infile ); FileOutputStream fout = new FileOutputStream( outfile ); FileChannel fcin = fin.getChannel(); FileChannel fcout = fout.getChannel(); ByteBuffer buffer = ByteBuffer.allocateDirect( 1024 ); while (true) { buffer.clear(); int r = fcin.read( buffer ); if (r==-1) { break; } buffer.flip(); fcout.write( buffer ); }
而MMF的详细介绍,可以参考IBM上“如何提高系统性能指标”这篇文章:http://www.ibm.com/developerworks/cn/java/l-java-performance/index.html。