我可以理解为什么网络应用程序会使用多路复用(为了不创建太多线程),以及为什么程序会使用异步调用进行流水线(更高效)。但是我不理解AsynchronousFileChannel的效率目的。
有什么想法吗?
发布于 2010-05-04 18:02:58
这是一个你可以用来异步读取文件的通道,即I/O操作是在一个单独的线程上完成的,这样当I/O操作发生时,你调用它的线程可以做其他事情。
例如:类的read()方法返回一个Future对象,以获取从文件读取数据的结果。因此,您可以做的就是调用read(),它将立即返回一个Future对象。在后台,另一个线程将从文件中读取实际数据。您自己的线程可以继续执行任务,当它需要读取的数据时,您可以在Future对象上调用get()。这将返回数据(如果后台线程尚未完成读取数据,它将使您的线程阻塞,直到数据就绪)。这样做的好处是,您的线程不必等待整个读操作;它可以做一些其他事情,直到它真正需要数据。
参见the documentation。
请注意,AsynchronousFileChannel将是JavaSE7中的一个新类,该类尚未发布。
发布于 2012-02-15 14:36:00
我刚刚发现了使用AsynchronousFileChannel的另一个令人意想不到的原因。当在NTFS上跨大文件执行面向记录的随机写操作(超过物理内存,因此缓存并不是万能的)时,我发现AsynchronousFileChannel在单线程模式下执行的操作是普通FileChannel的两倍多。
我最好的猜测是,因为异步io归结为Windows7中的重叠IO,所以NTFS文件系统驱动程序能够更快地更新自己的内部结构,而不必在每次调用后创建同步点。
我对RandomAccessFile进行了微基准测试,看看它的表现如何(结果非常接近FileChannel,性能仍然是AsynchronousFileChannel的一半。
不确定多线程写入会发生什么。这是在Java 7上,在SSD上( SSD比磁性快一个数量级,在内存中可以容纳的较小文件快另一个数量级)。
看看同样的比率是否适用于Linux将会很有趣。
发布于 2015-07-28 10:02:08
我能想到的使用异步IO的主要原因是为了更好地利用处理器。想象一下,你有一个应用程序,它对一个文件进行某种处理。另外,假设您可以按块处理文件中包含的数据。如果你不使用异步IO,那么你的应用程序可能会表现如下:
处理器利用率将上升,然后为零,然后上升,然后为零,...。理想情况下,如果希望应用程序高效并尽可能快地处理数据,则不希望空闲。更好的方法是:
第一步是引导。您还没有数据,所以您必须发出一个read。从那时起,当您收到读取已完成的通知时,您将发出另一个异步读取,然后处理数据。这里的好处是,当您完成处理数据块时,下一次读取可能已经完成,因此您始终有数据可供处理,因此您可以更有效地使用处理器。如果您的处理在读取完成之前完成,则可能需要发出多个异步读取,以便有更多的数据需要处理。
尼克
https://stackoverflow.com/questions/2762987
复制相似问题