在Java对象上同步文件访问

在Java对象上同步文件访问

本文介绍了在Java对象上同步文件访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个对象负责将JTable状态持久化到磁盘.它保存/加载可见列,它们的大小,位置等.下面是其类定义中的一些有趣的内容.

I have an object responsible for persisting JTable state to disk. It saves/loads visible columns, their size, position etc. A few interesting bits from its class definition are below.

class TableSaver {
    Timer timer = new Timer(true);

    TableSaver() {
        timer.schedule(new TableSaverTimerTask(), 15000, SAVE_STATE_PERIOD);
    }

    synchronized TableColumns load(PersistentTable table) {
        String xml = loadFile(table.getTableKey());
        // parse XML, return
    }

    synchronized void save(String key, TableColumns value) {
        try {
            // Some preparations
            writeFile(app.getTableConfigFileName(key), xml);
        } catch (Exception e) {
            // ... handle
        }
    }

    private class TableSaverTimerTask extends TimerTask {
        @Override
        public void run() {
            synchronized (TableSaver.this) {
                Iterator<PersistentTable> iterator = queue.iterator();
                while (iterator.hasNext()) {
                    PersistentTable table = iterator.next();
                    if (table.getTableKey() != null) {
                        save(table.getTableKey(), dumpState(table));
                    }
                    iterator.remove();
                }
            }
        }
    }
}

  • 永远只有一个TableSaver实例.
  • load()可以从许多线程中调用.计时器显然是另一个线程.
  • loadFile()writeFile()不会保留打开的文件流-它们使用功能强大,经过良好测试且用途广泛的库,该库始终使用try ... finally关闭流.
    • There only exists one instance of TableSaver, ever.
    • load() can be called from many threads. Timer clearly is another thread.
    • loadFile() and writeFile() do not leave open file streams - they use a robust, well tested and broadly used library which always closes the streams with try ... finally.
    • 有时这会失败,并出现以下异常:

      Sometimes this fails with an exception like:

      java.lang.RuntimeException: java.io.FileNotFoundException: C:\path\to\table-MyTable.xml (The requested operation cannot be performed on a file with a user-mapped section open)
          at package.FileUtil.writeFile(FileUtil.java:33)
          at package.TableSaver.save(TableSaver.java:175)
          at package.TableSaver.access$600(TableSaver.java:34)
          at package.TableSaver$TableSaverTimerTask.run(TableSaver.java:246)
          at java.util.TimerThread.mainLoop(Unknown Source)
          at java.util.TimerThread.run(Unknown Source)
      Caused by: java.io.FileNotFoundException: C:\path\to\table-MyTable.xml (The requested operation cannot be performed on a file with a user-mapped section open)
          at java.io.FileOutputStream.open(Native Method)
          at java.io.FileOutputStream.<init>(Unknown Source)
          at java.io.FileOutputStream.<init>(Unknown Source)
          at package.FileUtilWorker.writeFile(FileUtilWorker.java:57)
          ... 6 more
      

      所以我有两个问题:

      1. 这种同步如何失败?请注意,我确定只有TableSaver的一个实例.
      2. 堆栈跟踪中的这是什么:package.TableSaver.access$600(TableSaver.java:34)?第34行是带有class TableSaver {的行.这可能是同步无法正常工作的原因吗?
      1. How can this kind of synchronization fail? Note that I am sure there only is one instance of TableSaver.
      2. What is this thing in the stacktrace: package.TableSaver.access$600(TableSaver.java:34)? Line 34 is the line with class TableSaver {. Can this be the reason why the synchronization is not working?

      推荐答案

      Google 告诉我,这似乎是Windows特定的.这是错误6354433 的摘录:

      Google learns me that this seems to be Windows specific. Here's an extract of Bug 6354433:

      您使用的是哪个Java/Windows版本?它有最新的更新吗?

      What Java/Windows version are you using? Does it have the latest updates?

      还有另外两个相关的错误,并提供了一些有用的见解:

      Here are two other related bugs with some useful insights:

      • Bug 4715154 - Memory mapped file cannot be deleted.
      • Bug 4469299 - Memory mapped files are not GC'ed.

      关于第二个问题,那只是内部或匿名类的自动生成的类名.

      As to your second question, that's just the autogenerated classname of an inner or anonymous class.

      这篇关于在Java对象上同步文件访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 19:15