Java 访问EclipsePreferences的线程安全方式(项目)
我目前正在开发一个Eclipse RCP应用程序,它通过ProjectScope使用EclipsePreference机制存储每个项目的首选项。起初,这似乎工作得很好,但在多线程场景中(读取-)访问这些首选项的同时对工作区进行更改时,我们遇到了麻烦。在异步用户操作(右键单击project->Delete project)删除项目时,访问这样一个首选项节点(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
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测试的压力测试)。