2011-09-11 85 views
1

ServiceTracker被定義爲OSGI 4.2規範中的線程安全級別OSGI ServiceTracker和線程安全

該類的用法非常簡單。

大部分採用ServiceTracker的,我可以在互聯網上找到的例子顯示的代碼片段如下所示:

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

現在我的問題是:一旦服務實現對象從ServiceTracker的檢索,有不能保證在空檢查後立即可用(不會被刪除)。

換句話說,即使在如週期,服務對象(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在行動)談論這個要求......

我說得對不對?我錯過了什麼嗎?

回答

2

你基本上是正確的,但是問題是在你自己的代碼中處理異常還是讓它將調用棧喚醒到某種全局處理程序。

我認識的大多數OSGi開發人員,包括我自己在內,都更喜歡允許從這個級別拋出異常的方法。在可能發生的每一點上捕捉異常會導致可怕的臃腫代碼。

從某種意義上來說,這是辯論和未經檢查的例外之爭的核心。

請注意一個小的更正:您的參考變量serviceObj在空檢查後不能成爲null,因爲它是一個局部變量,其他線程永遠不能更改您的局部變量的值。但是,正如您推斷的那樣,服務參考可能會失效或無法使用。這種情況發生的可能性非常小,儘管如果你只是從跟蹤器中檢索到引用。

+0

謝謝您的回答 –

+0

Re:null。你提出了一個有關空值問題的有趣觀點。你是對的:一個局部變量不能在其範圍之外被修改。因此,引用**將保持有效**直到它超出範圍。現在從我讀到的關於Osgi的內容來看,我們通過查詢服務註冊表得到的參考資料不過是實際的服務實現類(一個java類)。因此,我的代碼應該始終工作,if-cycle中的異常永遠不會被拋出......我在這裏丟失了什麼? –

+0

PS:根據我的經驗,我確實得到了一個空指針異常至少一次 –