为什么InputStream读取方法会阻塞资源?

时间:2019-03-01 01:11:34

标签: java multithreading randomaccessfile

为什么什么也没读,InputStream的read方法为什么会阻塞资源?

假设我在RW模式下打开了RandomAccessFile,然后使用文件描述符创建InputStream / OutputStream。

线程1尝试从文件读取,而没有可用的内容。 此时,如果线程2尝试写入文件,则该文件将被阻止。

为什么会这样?

1 个答案:

答案 0 :(得分:1)

FileDescriptor是带有OS文件句柄的对象,这意味着它是带有文件指针的对象。

因为FileDescriptor不支持多线程,所以一个线程一次只能使用文件句柄/文件指针。访问已同步。

如果您希望两个线程具有对文件的独立访问权限,则需要两个FileDescriptor。

为证明我的共享文件指针观点,如果您交替读取FileInputStream并写入FileOutputStream,您会怎么想?

以下代码显示发生的情况:

String fileName = "Test.txt";
Files.writeString(Paths.get(fileName), "abcdefghijklmnopqrstuvwxyz", StandardCharsets.US_ASCII);

try (RandomAccessFile raFile = new RandomAccessFile(fileName, "rw");
     FileInputStream in = new FileInputStream(raFile.getFD());
     FileOutputStream out = new FileOutputStream(raFile.getFD()) ) {

    byte[] buf = new byte[4];
    for (int i = 0; i < 3; i++) {
        int len = in.read(buf);
        System.out.println(new String(buf, 0, len, StandardCharsets.US_ASCII));

        out.write("1234".getBytes(StandardCharsets.US_ASCII));
    }
}

String s = Files.readString(Paths.get(fileName), StandardCharsets.US_ASCII);
System.out.println(s);

输出

abcd
ijkl
qrst
abcd1234ijkl1234qrst1234yz

如您所见,读取4个字节将返回字节0-3并移动文件指针,因此写入4个字节将替换字节4-7,然后读取4个字节将返回字节8-11,写入4个字节将替换字节12-15,依此类推。