问题描述
我有一个对象负责将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()
andwriteFile()
do not leave open file streams - they use a robust, well tested and broadly used library which always closes the streams withtry ... 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
所以我有两个问题:
- 这种同步如何失败?请注意,我确定只有
TableSaver
的一个实例. - 堆栈跟踪中的这是什么:
package.TableSaver.access$600(TableSaver.java:34)
?第34行是带有class TableSaver {
的行.这可能是同步无法正常工作的原因吗?
- How can this kind of synchronization fail? Note that I am sure there only is one instance of
TableSaver
. - What is this thing in the stacktrace:
package.TableSaver.access$600(TableSaver.java:34)
? Line 34 is the line withclass 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对象上同步文件访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!