FileChannel怎么来的
FileChannel channel = new FileInputStream("").getChannel()
FileChannel的read()方法
channel.read(byteBuffer)
实现类FileChannelImpl
首先映入眼帘的就是非常熟悉的synchronized关键字,
private final Object positionLock = new Object();
原来是线程安全的啊,这不是最主要的我们继续看
var3 = IOUtil.read(this.fd, var1, -1L, this.nd);
进入readIntoNativeBuffer
进入此行var9 = var4.read(var0, ((DirectBuffer)var1).address() + (long)var5, var7);的read方法,实现类FileDispatcherImpl
进入read0
原来调用的是FileDispatcherImpl的native方法read0啊,那好我们跟着这个线索去查找jdk源码。
首先打开网页OpenJDK Mercurial Repositories
点击native后,查看java类的包名
原来,read0方法底层使用的ReadFile方法。
FileInputStream的read()方法
进入readBytes方法
原来 FileInputStream的read并没有像FileChannel的read那样加锁,底层使用的是native方法readBytes,那是不是他们两者底层实现就一定不相同呢,不要下这么早的结论,我们看jdk源码,步骤大致像上述那样,但是有些区别,先进入OpenJDK Mercurial Repositories
这次选择jdk8u-dev
选择
这个时候我们像刚才那样一样进入FileInputStream_md.c,h会发现,怎么没有代码。
看着行
原来调用了工具类的 readBytes方法。
找到readBytes方法,发现调用了IO_Read方法
IO_Read是什么呢?看c语言对io_util的定义文件io_util_md.h
jdk8u/jdk8u-dev/jdk: 7fcf35286d52 src/windows/native/java/io/io_util_md.h
搜索 IO_Read
使用了宏定义#define IO_Read handleRead
回到io_util_md.h实现文件io_util_md.cjdk8u/jdk8u-dev/jdk: 7fcf35286d52 src/windows/native/java/io/io_util_md.c
搜素handleRead
原来 FileInputStream的read方法底层也是调用的ReadFile方法。
相同点:都是调用c语言io_util_md.c库文件中的核心方法ReadFile()。
不同点:FileInputStream的read方法是非线程安全的,FileChannel的read方法是线程安全的。