1

私の問題は、メイン クラスに、クラスが呼び出されたときに問題なく動作する osgi 参照がいくつかあることです。しかしその後、すべての参照が null になりました。メイン ウィンドウを閉じて shutdown メソッドを呼び出すと、hubService 参照が null を返します。ここで何が間違っていますか?

private void shutdown() {
if(hubService == null) {
    throw new NullPointerException();
}
hubService.shutdownHub(); // why is hubService null?
}

// bind hub service
public synchronized void setHubService(IHubService service) {
hubService = service;
try {
    hubService.startHub(PORT, authenticationHandler);
} catch (Exception e) {
    JOptionPane.showMessageDialog(mainFrame, e.toString(), "Server", JOptionPane.ERROR_MESSAGE);
    System.exit(0);
}
} 

// remove hub service
public synchronized void unsetHubService(IHubService service) {
hubService.shutdownHub();
hubService = null;
}
4

2 に答える 2

0

フィールドが複数のスレッドによって読み書きできる場合は、読み取りアクセスと書き込みアクセスを保護する必要があります。最初の方法である shutdown は、hubService の読み取りを保護しないため、hubService の値は最初の読み取りと 2 番目の読み取りの間で変化する可能性があります。hubService フィールドの宣言は表示されません。揮発性にするか、同期時に読み取りのみにすることができます (フィールドの書き込み時に同期に使用された同じオブジェクトで)。次に、シャットダウンの実装は次のようになります。

private volatile IHubService hubService;
private void shutdown() {
    IHubService service = hubService; // make a copy of the field in a local variable
    if (service != null) // use local var from now on since the field could have changed
        service.shutdownHub();
}
于 2012-10-22T15:50:08.267 に答える
0

あなたのシャットダウン方法はDSの無効化方法だと思いますか?もしそうなら、なぜunsetメソッドでもshutdownメソッドでもshutdownするのですか?

全体的に、デザインはあまり健全ではないようです。IHubService はファクトリとして使用され、deactivate メソッドで閉じられる何らかのオブジェクトを返す必要があります。IHubService を事実上シングルトンにしました。別のバンドルから取得する必要があるため、ライフサイクル自体を処理する必要があります。

注釈も使用しないため、設定/設定解除メソッドが静的/動的および/または単一/複数であるかどうかは明確ではありません。次のコードには問題はありません (bnd 注釈付きのコード例):

@Component public class MyImpl {
    IHubService hub;

    @Activate
    void activate() {
      hubService.startHub(PORT, authenticationHandler);
    }

    @DeActivate
    void deactivate() {
      hubService.shutdown();
    }

    @Reference
    void setHub(IHubService hub) { this.hub = hub; }
 }
于 2012-10-23T14:43:51.090 に答える