在OSGI4.2规范中,ServiceTracker被定义为线程安全类
这个类的用法非常简单。
我可以在互联网上找到的使用ServiceTracker的大多数示例都显示了如下代码片段:
ServiceInterface serviceObj = (ServiceInterface) serviceTracker.get();
if(serviceObj != null) {
// ...
// do smth with the serviceObject
// ...
}现在我的问题是:一旦从serviceTracker检索到服务实现对象,就不能保证它在null检查后立即可用(不会被删除)。
换句话说,即使在if周期内,服务对象(serviceObj)也很可能突然变为空(如果相应的服务未注册)。
因此,我们应该始终像这样纠正上面的代码:
ServiceInterface serviceObj = (ServiceInterface) serviceTracker.get();
if(serviceObj != null) {
try {
// ...
// do smth with the serviceObject
// ...
} catch(Throwable th) {
// a null-pointer exception may have occurred here!!
}
}尽管如此,在博客(http://developers-blog.org/blog/default/2010/03/31/OSGI-Tutorial-How-to-use-ServiceTracker-to-get-Services)或书籍(Osgi in Action)中都没有例子谈到这一要求……
我说的对吗?我是不是遗漏了什么?
发布于 2011-09-11 19:15:29
您基本上是正确的,但是问题是是在您自己的代码中处理异常,还是允许它在调用堆栈中冒泡到某种全局处理程序。
我认识的大多数OSGi开发人员,包括我自己,都喜欢允许从这个级别抛出异常的方法。在可能发生的每一点捕获异常都会导致严重膨胀的代码。
从某种意义上说,这切中了受控异常和未受控异常之间争论的核心。
注意一个小更正:您的引用变量serviceObj在null检查后不能变成null,因为它是一个局部变量,并且其他线程永远不能改变您的局部变量的值。但是,正如您推断的那样,服务引用可能会失效或失效。不过,如果您刚刚从跟踪器中检索到引用,则发生这种情况的可能性很小。
https://stackoverflow.com/questions/7377481
复制相似问题