OSGI ServiceTracker和线程安全

时间:2011-09-11 10:00:45

标签: thread-safety osgi

ServiceTracker被定义为OSGI 4.2规范中的线程安全类

这门课程的使用非常简单。

我在互联网上找到的使用ServiceTracker的大多数示例都显示了以下代码片段:

ServiceInterface serviceObj = (ServiceInterface) serviceTracker.get();
if(serviceObj != null) {
  // ...
  // do smth with the serviceObject
  // ...
}

现在我的问题是:一旦从serviceTracker检索到服务实现对象,就无法保证在空检查之后它立即可用(不会被删除)。

换句话说,即使在if-cycle中,服务对象(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)中没有例子谈论这个要求...

我是对的吗?我错过了什么吗?

1 个答案:

答案 0 :(得分:2)

你基本上是正确的,但问题是在你自己的代码中处理异常还是允许它将调用堆栈冒泡到某种全局处理程序。

我认识的大多数OSGi开发人员和我自己都喜欢允许从这个级别抛出异常的方法。在他们可能发生的每一点上捕获异常会导致代码非常臃肿。

从某种意义上说,这是检查和未检查例外之间争论的核心。

请注意一个小的更正:您的引用变量serviceObj在null检查后不能成为null,因为它是一个局部变量,而其他线程永远不能更改局部变量的值。但是,正如您所推断的那样,服务引用可能会失效或不起作用。如果您刚刚从跟踪器中检索了引用,则发生这种情况的可能性非常小。