2017-01-04 10 views
1

私はオブジェクトを作成し、2つの異なるスレッドでアクセスするJavaでコードを記述しています。私の最初のthread1スレッドは、このオブジェクトのいくつかのパブリックメソッドを実行時に呼び出します。Javaでオブジェクトがnullであることを確認します。

final Thread thread1 = new Thread(){ 
    @Override 
    public void run() { 
     myObj.pubFunc1(); 
     myObj.puFunc2(); 
     myObj.pubFunc3(); 
    } 
}; 

私は、このオブジェクトを解放などnullにそれを設定するかもしれません別のスレッドthread2持っている:私はこのように私のthread1に各ステートメントの周りnullにチェック入れなければならない場合

final Thread thread2 = new Thread(){ 
    @Override 
    public void run() { 
     myObj.release(); 
     myObj = null; 
    } 
}; 

を私の質問はありますか?

final Thread thread1 = new Thread(){ 
     @Override 
     public void run() { 
      if(myObj != null) { 
       myObj.pubFunc1(); 
      } 
      if(myObj != null) { 
       myObj.pubFunc2(); 
      } 
      if(myObj != null) { 
       myObj.pubFunc3(); 
      } 
     } 
    }; 

またはすべてのステートメントの周りに1つのチェックだけで十分ですか?これから生じるかもしれない基本的な質問は、私たちがヌルチェックをしたオブジェクトの周りにロックがあるということですか?この状況をどう扱うか。このような状況に対応するためには、どのようなデザインパターンを使用すべきですか。

NOTE:私は3つのステートメントを必ず実行する必要はなく、3つのステートメントがアトミックユニットを形成することも望んでいません。私は、操作を実行しているオブジェクトがnullでない場合、操作を実行したいだけです。

+3

オブジェクトが非同期にnullになる可能性がある場合は、オブジェクトをチェックする必要があります。また、 'synchronized'ブロックまたはメソッドでのみ' volatile'または読み書きする必要があります。これは「デザインパターン」ではなく、JLSから生じる常識です。 – EJP

答えて

3

あなたの提案に欠陥があります。この実行を想像:

  • myObj = new MyObject();
  • スレッド2:if (myObjec != null) =>すべての良い、オブジェクトはnullではありません
  • スレッド1:myObj.release(); myObj = null;
  • スレッド2:myObj.pubFunc1(); =>ブーム、NPE。 - この

    • あなたがもし/ pubFuncは原子
    • を呼び出したり、オブジェクトのローカルコピーを保存するためにmyObjへのアクセスを同期させるのいずれか:私はあなただけ2つのオプションを持っていると思う

    よく、またはあなたのユースケースによっては許容できないことがあります。

    public void run() { 
        MyObject localObj = myObj; 
        if (localObj != null { //NOTE: myObj may have been released 
        localObj.pubFunc1(); 
        localObj.puFunc2(); 
        localObj.pubFunc3(); 
        } 
    } 
    

注:私はあなたが可視性の問題を認識しており、myObjが適切に公開/同期されていると仮定します。

+0

私は同期されているオブジェクトの意味を理解しています。 「出版された」とは、正確には何を意味しますか?また、「可視性の問題」と言えば、プライベート、パブリック、プロテクト、パッケージレベルの可視性に関連していると思いますか? – Swapnil

+0

@Swapnilいいえ、私はスレッド間の可視性を意味しませんでした。例えば、私は 'myObj'がスレッドが起動する前に完全に作成されているか、またはvolatileであると考えます。また、さまざまな方法(pubFunc1など)がスレッドセーフであることも前提としていました。 – assylias

+0

だから私が今まで理解しているのは、あなたが 'null'チェックと3つの関数呼び出しをsynchronizedmy(Obj)(nullチェックにも囲まなければならない)の中に持つことを提案するということです。メソッドがスレッドセーフであると言うとき、それらの宣言とキーワード 'synchronized'があることを意味しますか? – Swapnil

関連する問題