【问题标题】:OSGI ServiceTracker and thread-safetyOSGI ServiceTracker 和线程安全
【发布时间】:2011-09-11 10:00:44
【问题描述】:

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

这个类的用法非常简单。

我可以在互联网上找到的大多数使用 ServiceTracker 的示例都显示了如下所示的 sn-p 代码:

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

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

换句话说,即使在if-cycle内,服务对象(serviceObj)也很可能突然变为null(如果相应的服务未注册)

因此,我们应该始终像这样更正上面的代码:

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) 中没有任何示例讨论此要求...

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

【问题讨论】:

    标签: thread-safety osgi


    【解决方案1】:

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

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

    从某种意义上说,这触及了受检异常和未受检异常之间争论的核心。

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

    【讨论】:

    • 回复:空。您就空值问题提出了一个有趣的观点。你是对的:不能在其范围之外修改局部变量。因此,引用将保持有效,直到超出范围。现在从我所读到的关于 Osgi 的内容中,我们通过查询服务注册表获得的引用只不过是实际的服务实现类(一个 java 类)。因此,我的代码应该始终有效,并且永远不应该抛出 if 循环中的异常......我在这里错过了什么??
    • PS:根据我的经验,我确实至少得到了一次空指针异常
    • 我认为您没有遗漏任何东西。服务引用不能变为空,但服务本身可以变为无效。例如,假设服务代表插入 USB 端口的设备的功能。该设备被删除,不久之后该服务将被取消注册等。您可能会在该窗口中获得对该服务的非空引用,但如果您调用它,它将失败,即可能会抛出一些古怪的 RuntimeExceptions。这没关系,因为服务并不意味着 100% 可靠。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    相关资源
    最近更新 更多