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方法是线程安全的。



















