没有系统调用的* * nix sync()的Java实现

时间:2012-11-12 22:29:31

标签: java system-calls

我正在努力从现有的Java代码库中删除所有系统调用。我们在商业提供的闭源JVM中运行我们的应用程序。当JVM通过getRuntime.exec()进行系统调用时,java会调用整个JVM进程分支,从而导致严重的性能命中。我们在Linux平台上运行,但最好尽量保持便携性。

我遇到了通过getRuntime.exec()方法替换我们当前使用的sync()调用的问题。我知道有this sync()方法和flush()。并基于this post我正在寻找同步并刷新所有打开的文件流。

我的问题是我不知道哪些文件流和描述符在那里。我认为解决这个问题的方法是检查/ proc /(jvm进程号)/ fd文件夹但我找不到使用纯java可靠地获取JVM进程号的好方法。我以为我可以获得某个类的所有对象(FileDescriptor类)但是从我正在阅读的内容中也是不可行的。

有没有人有关于如何在纯java中复制* nix sync()调用的建议?

1 个答案:

答案 0 :(得分:4)

您正在做的是更多 sync来电。您正在尝试执行“刷新所有文件缓冲区和sync”操作。你也无法在C / C ++中做这件事。

除了找到所有打开文件(你可能解决的问题......)之外,还有一个更大的问题;即,是否正确的时间来刷新缓冲区。

让我们假设您的应用程序是多线程的,并且一个线程负责调用sync。该线程如何知道正在编写文件的其他线程已达到文件的一致点;即如果应用程序被杀死并重新启动,那么(假设)刷新的文件将包含应用程序的逻辑一致状态?答案是(很可能)它知道。所以...实际上......如果应用程序在同步之前刷新,则应用程序的位置不会明显更好。

还有另一个问题。假设线程A负责刷新/同步,并且线程B正在愉快地写入某个输出流。考虑这个时间序列:

  1. 线程A刷新文件
  2. 线程B写入文件
  3. 主题A调用同步
  4. 避免这种情况的唯一方法是让线程A同步并阻止所有其他正在写入文件的线程... 之前它执行刷新和同步。

    我的建议是只做同步,忘记刷新。以经典方式处理不一致文件的问题(通过让应用程序写入临时文件,并进行原子重命名),或者让同步线程与写入文件的线程协调...以便它只有当关键文件一致时才“同步”。