2011-09-11 11 views
1

ServiceTrackerが4.2スペックOSGI ServiceTrackerとスレッドの安全性

このクラスの使用はかなり単純ですOSGIにスレッドセーフなクラスとして定義されます。

私はインターネット上で見つけることができる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。あなたはnull値の問題について興味深い点を挙げました。あなたは正しい:ローカル変数はそのスコープの外で変更することはできません。したがって、参照**は範囲外になるまで**有効のままです。今私がOsgiについて読んだことは、サービスレジストリを照会することによって得られる参照は、実際のサービス実装クラス(Javaクラス)にすぎないということです。したがって、私のコードは常に動作し、if-cycleの例外は投げられるべきではありません...私はここで何が欠けていますか? –

+0

PS:私の経験ではなく、少なくとも1回Null Pointer例外が発生しました –