我现在正在学习Java NIO.2 API,我做了一个测试来比较AIO和标准IO之间的效率,测试是写一个2000M文件。这是代码。
标准方式:
FileOutputStream output = new FileOutputStream(tmp);
byte[] byteArr = new byte[1024 * 1024];
for (int i = 0; i < 1024 * 1024; i++) {
byteArr[i] = 1;
}
long start = System.currentTimeMillis();
while (length -- > 0) {
output.write(byteArr);
}
System.out.println("taking time:" + (System.currentTimeMillis() - start) + "ms");
结果为taking time:10392ms
AIO方式:
AsynchronousFileChannel afc = AsynchronousFileChannel.open(path, WRITE, CREATE);
List<Future<Integer>> results = new ArrayList<>();
ByteBuffer buf = ByteBuffer.allocate(1024 * 1024);
buf.clear();
for (int j = 0; j < 1024 * 1024; j++) {
buf.put((byte) 1);
}
buf.flip();
buf.mark();
long start = System.currentTimeMillis();
for (int i = 0; i < 2000; i ++) {
buf.reset();
results.add(afc.write(buf, i * 1024 *1024));
}
for(Future<Integer> future : results) {
future.get();
}
System.out.println("taking time:" + (System.currentTimeMillis() - start) + "ms");
结果为taking time:15652ms
我认为,在第二种情况下,该程序向操作系统提交了2000个写入请求。操作系统将使用它自己的线程池运行IO操作。换句话说,thread pool size
IO操作将同时执行。在第二种情况下,它应该更快。但事实正好相反,为什么?
答案 0 :(得分:-1)
在程序提交写入请求之前,文件被锁定直到写入操作结束。换句话说,AsynchronousFileChannel
同时只允许一个操作。因此多线程无效。