2017-08-08 1 views
-1

以下のコードが完全にスレッドセーフであり、 "this"リファレンスがリークしないかどうかについて、私は感謝していますか?私がやろうとしているのは基本的にExecutorServiceを使ってバックグラウンドスレッドで別のサービスをブートストラップ/初期化することです。コンストラクタでのJavaの安全なパブリケーション、 "this"リファレンスが漏れないようにする

私は、クラスが完全に構築される前に "this"参照をリークするので、コンストラクタからスレッドを開始することは悪い習慣であるとどこかから読んだので、少し気になります。

public class MyService { 

private final ExecutorService executorService; 
private volatile AnotherService anotherService; 
private volatile boolean isReady = false; 


public MyService(final ExecutorService executorService) { 
    this.executorService = executorService; 
    start(); 
} 

private void start() { 
    executorService.submit(new Runnable() { 
     @Override 
     public void run() { 
      try { 
       anotherService = init(); 
       isReady = true; 
      } catch (Exception e) { 
       // do nothing, just retry later 
      } 
     } 
    }); 
} 

private AnotherService init() { 
    // some code to initialize 
    return AnotherServiceBootstrap.getInstance().bootstrap(); 
} 

// some other methods in class 

} 

事前に感謝します。

+0

MyServiceの2つのインスタンスを同時に2つのスレッドで作成し、それらの一方または両方が間違ったスレッドのexecutorServiceで終了することが懸念されますか? –

+0

私はこの種のものはあまりにも複雑で不必要だと思います。あなたはそのサービスを呼び出すことを知っていますか?次に、作成したオブジェクトの各インスタンスにサービス参照を作成または挿入します。これにはどんなメリットがありますか? – duffymo

+0

ここで説明しているように 'volatile boolean'の代わりに' AtomicBoolean'を使うべきですhttps://stackoverflow.com/a/3787435/6138873 – jeanr

答えて

0

私はあなたのコードを持つすべてのリスクを持っていないと思う -

  1. その記事で説明が与えられthis question
  2. を参照してください誰かが最後のメンバだけにアクセスすることができれば、あなたが持っていた唯一のリスクがあります(executorService)が生成されます。しかし、変数がそのようにアクセスされる唯一の場所は、作成して実行系サービスに送信するスレッド内のものです。そして、submit()メソッドが実行される前に、あなたが作成したスレッドが実行される前に、あなたのコンストラクターが今までに行ったすべての変更を示すfuture-before保証を取得します。私はあなたがカバーされていると信じています。
関連する問題