2011-02-24 17 views
0

私はリファレンスと同期キーワードに関する問題で長時間混乱しています。 私は通常、このようないくつかのコードを参照してください。メンバ変数を置き換えるために地元の最後の変数OBJを使うべき理由Javaリファレンスと同期キーワードの実践についての質問?

Class someClass { 
    ... 
    private SomeObject mObject; 
    ... 
    public void someMethod() { 
     ... 
     final SomeObject obj = mObject; 
     ... 
     //then use the 'obj' variable rather than mObject 
     ... 
    } 

}

を私の質問はありますか? メンバー変数を直接使用しないのはなぜですか?

私はまた、このように、「同期」キーワードに関連するいくつかのサンプルコードを参照してください。

public void write(byte[] out) { 
    // Create temporary object 
    ConnectedThread r; 
    // Synchronize a copy of the ConnectedThread 
    synchronized (this) { 
     if (mState != STATE_CONNECTED) return; 
     r = mConnectedThread; 
    } 
    // Perform the write unsynchronized 
    r.write(out); 
} 

これらのコードは、同期目標を達成することができますなぜ? ありがとう!

+0

2番目のサンプルは、著者がもちろん達成しようとしていることに依存して、私に欠陥があるようです。 –

+0

私はmStateとmConnectedThreadと 'this'の関係やこのコードの目的が何であるかを理解していないので、本当に同期の例については答えられません。別のスレッドは同期ブロックの後でr.write(out)の前にmConnectedThreadをロックすることができますが、それ以上の情報がなければ問題があるかどうかわかりません。 –

答えて

0

最初の質問に関しては、メソッドがオブジェクトを変更できないことを確認しています。後で何かを再割り当てしないことを確実にしている最終変数にエイリアスを付けることでオブジェクトを変更できますか?私は確信していません...

2番目の質問 これは、mStateが接続されていない場合、メソッドから戻り、r.write()が実行されないため、これが機能します。オブジェクト自体をロックとして使用します。

+1

mStateが接続されていない場合です。 – Rich

+0

しかし、同期ブロックから 'r = mConnectedThread'を移動することができます。以前と同じ結果になると思います。 –

+1

しかし、mConnectedThreadは、同期ブロックの直後で、r.write(out)の呼び出しの前に別​​のスレッドによってヌルに設定される可能性があります。 – Nick

0

最初の例では、メンバ変数が別のスレッドで変更された場合、メンバ関数のコピーは同じままになるように、メンバ変数のコピーを最終的なローカル変数に取り込むことを考えています。

2番目の例は、現在接続されているスレッドのコピーをローカル変数に入れている点で似ています。

メンバ変数(または接続されたスレッド)が直接アクセスされ、別のスレッドによって関数呼び出しの途中で変更された場合、未定義の動作が発生する可能性があります。

私はこのコーディングパターンの名前があると確信していますが、私はそれを覚えていません!

+0

しかし、あなたはコピーを取っておらず、新しい変数を使って同じオブジェクトを指しています。はい、mObjectの参照が別のスレッドで変更されている場合は、このスレッドから保護されていますが、問題のインスタンスへのアクセスは同期していません。 – Rich

+0

実際には、コピーを取っているだけです。参照のコピーがあるので、ローカル変数はメンバ変数と同じオブジェクトを指しています。 – Nick

+0

それは私が言ったことです: "あなたは新しい変数で同じオブジェクトを指している"。 – Rich

0

私はあなたの質問と最初の例を理解することができますから、コードはスレッド変数のローカルコピーを取ることによって問題を回避しようとしています。最初の例ではこれをしませんが、メンバ変数が指しているのと同じオブジェクトを指す新しいローカル変数を取得しますが、実際にはそのオブジェクトの呼び出しをスレッドの問題から保護しません。

次のように編集してください:@ Nickのコメント:最初の例のsomeMethodメソッドは、mObjectが途中まで別のインスタンスに置き換えられる可能性を回避します。しかし、同じインスタンス上の同時起動によるスレッドの問題を防ぐことはできません。

+1

実際には、メンバ変数を変更する別のスレッドから保護されます。 – Nick

0

1> 私は最初の質問...メンバー変数は他のいくつかの方法でも参照オブジェクトを使用できるため、直接使用されていないと思います。他の方法でも必須ではありませんメソッドのように最後に宣言したように....その変数のローカル参照を作成するのは良い習慣です.....

2> いくつかの参照オブジェクトが同時にアクセスされているとしますスレッドを使用しています....もしそのオブジェクトがいくつかのデータを変更すると、そのデータの同時アクセスの整合性が失われてしまいます....そのオブジェクト参照上に何らかの種類のロックが存在する必要があります。そのオブジェクトの参照のいくつかの他のスレッドはablであってはならないそれにアクセスするには....この同期キーワードは、それを達成するために使用されます...

関連する問題