this question中的结果(fsync
将目录打开为常规文件,似乎暗示FileChannel#force()
适用于对文件所做的所有更改,无论哪个文件使用了描述符。
由此提示我尝试优化我的文件编写过程,这样我就会启动一个后台线程,它打开同一个文件并在循环中调用force(false)
。当我的主写入线程到达终点并调用force(false)
本身时,它应该受到较少阻塞的影响,因为脏缓存页中剩下的数据会更少。这是我写的代码:
private static class Fsyncer implements Runnable {
volatile File requested;
File actual;
FileChannel fc;
@Override public void run() {
try {
while (!interrupted()) {
if (requested != actual) {
if (fc != null) {
fc.close();
actual = requested;
fc = new FileInputStream(actual).getChannel();
}
}
if (fc != null) {
fc.force(false);
}
}
} catch (InterruptedException e) {
// thread done
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
用法:
Thread fsyncerThread = new Thread(fsyncer);
fsyncerThread.start();
writeFiles();
fsyncerThread.interrupt();
最后,writeFiles()
会
fsyncer.requested = file;
每次打开另一个文件。
但是,在没有背景强制线程的情况下,我没有测量任何差异。
关于force
的文档并不完全清楚:它表示它将保证通过本课程中定义的方法强制完成所有更改"但它没有'准确地说明它是否仅适用于同一个FileChannel
实例。
上述两个事实似乎是矛盾的:如果强制目录的黑客是可靠的(并且Lucene团队通过实际关闭机器来测试它)那么我的背景强制技术也应该有用。
由于某些特殊行为应用于fsync
目录,目录强制技术是否可靠,这不适用于我的案例?或者也许只有在FD关闭后才能传播来自另一个FD的变化?我正在寻找可以解释这两个发现的解释。