Java 访问EclipsePreferences的线程安全方式(项目)

Java 访问EclipsePreferences的线程安全方式(项目),java,eclipse,multithreading,eclipse-plugin,eclipse-rcp,Java,Eclipse,Multithreading,Eclipse Plugin,Eclipse Rcp,我目前正在开发一个Eclipse RCP应用程序,它通过ProjectScope使用EclipsePreference机制存储每个项目的首选项。起初,这似乎工作得很好,但在多线程场景中(读取-)访问这些首选项的同时对工作区进行更改时,我们遇到了麻烦。在异步用户操作(右键单击project->Delete project)删除项目时,访问这样一个首选项节点(ProjectScope.getNode())是一个实际问题。在这种情况下,我们得到了相当多的 org.osgi.service.prefs

我目前正在开发一个Eclipse RCP应用程序,它通过ProjectScope使用EclipsePreference机制存储每个项目的首选项。起初,这似乎工作得很好,但在多线程场景中(读取-)访问这些首选项的同时对工作区进行更改时,我们遇到了麻烦。在异步用户操作(右键单击project->Delete project)删除项目时,访问这样一个首选项节点(
ProjectScope.getNode()
)是一个实际问题。在这种情况下,我们得到了相当多的

  • org.osgi.service.prefs.BackingStoreException
  • java.io.FileNotFoundException
  • org.eclipse.core.runtime.CoreException
本质上,他们都抱怨底层文件不再存在

最初尝试使用诸如
IProject.exists()
isAccessible()
之类的检查来修复此问题,甚至检查实际的.prefs文件是否存在都是徒劳的:它们只会降低异常发生的可能性,但并不能真正阻止它们

所以我的问题是:您应该如何安全地访问像
ProjectScope.getNode()
这样的东西?您是否需要将每次读取都放入
工作空间作业
,或者是否有其他聪明的方法来防止上述问题,例如将读取访问放入
Display.asyncExec()

尽管我尝试过,但在Eclipse文档中并没有找到上述问题的答案。

通常用于并发访问工作区中的资源

我从未使用过
ProjectScope
ed首选项,但如果它们存储在项目或其元数据中,则调度规则应有助于协调访问。如果您正在作业中运行首选项访问代码,则设置适当的计划规则应:

例如:

IProject project=getProjectForPreferences(projectPreferences);
IsSchedulingRule rule=project.getWorkspace().getRuleFactory().modifyRule(项目);
作业作业=新作业(“访问项目首选项”){
@凌驾
受保护的IStatus运行(IProgressMonitor监视器){
if(project.exists()){
//读取或写入项目首选项
}
返回状态。OK_状态;
}
};
job.setRule(规则);
job.schedule();
代码获取一条规则来修改项目,并且只有当没有其他具有冲突规则的作业运行时,才能保证作业运行

如果代码未在作业中运行,还可以使用
IJobManager.beginRule()
endRule()
手动获取锁

例如:

isSchedulingRule=。。。;
试一试{
jobManager.beginRule(规则、监视器);
if(project.exists()){
//读取或写入项目首选项
}
}最后{
jobManager.endRule(规则);
}

尽管看起来很尴尬,但对
beginRule
的调用必须在try块内,请参阅以了解更多详细信息。

感谢您的快速回复,这种解决方案正是我所想到的,它非常适合EclipsePreferences API(它通过使用UI自动化和QF测试的压力测试)。