2016-05-24 9 views
1

...synchronizedメソッドと静的変数のアクセスJAVA /アンドロイド

だから私は最近、もしアプリが複数のスレッドを使用し、共有同じにアクセスする別のスレッドのいずれかの可能性があることを発見同じ変数を取得/設定するには、 "synchronized"メソッドを使用する必要があります。

私の(位置認識)アプリでは、LATとLONの変数がMainActivityに属しており、静的です。

appendToPOST(MainActivity.LAT); 

をそしてMainActivity自体に、私はGoogle Playで位置情報サービスを使用していますし、そうMainActivityでonLocationChanged()コールバックメソッドでは、私が持っている:彼らはそうのようなバックグラウンドサービスからアクセスされている

LAT = [arbitrary Double value goes here]; 

したがって、実装する必要があることを意味します。

正しいですか?明確化/助けていただきありがとうございます。

追加:変数と同じクラスに存在していても、synchronizedメソッドを使用するようにonLocationChanged()メソッドのコードを変更する必要がありますか?

+0

基本的な方法で、あなたは正しいですが、あなたの場合(すべてのメソッド)で 'synchronized'メソッドを持っているので、' multitThreading'は巨大なトピックを持っているあなたは、そのは、[デッドロック](http://www.javaworld.comに走っできるコード唯一のロックオブジェクト 'MainActivity'クラスが存在するように/article/2075692/java-concurrency/avoid-synchronization-deadlocks.html) – Hosseini

+0

@Hosseiniデッドロックは、与えられた例では問題にならないはずです。スレッドがこのロックオブジェクトを保持しているかどうか。他のロックオブジェクトと同様に同期を使用する他のクラスがある場合は、デッドロックが決定的に考慮すべき重要なことです。経験則として1を言うことができます:あなたのコードが使用されている場合は、複数の異なるロックは、これらのオブジェクトをオブジェクト**常に**同じ順序で取得する必要があります。残念ながら、それは我々が代わりにここで 'ゲッター/ setter'の任意のものが表示されていない、私たちはただ、これは仕方我々は' 'に入れてstate'保護する必要があるたびはないと言う – dpr

+0

...このルールを確保するために、常にその簡単ではありません同期化される。 – Hosseini

答えて

1

あなたの変更はこれまでのところ正しいです。そしてすでに言及したように、すべてこれらの共有状態変数へのアクセス(ローカルアクセスも同様)は、同期アクセサを使用している必要があります。

LATLONの値が一緒に属している場合(これらの値を持つ場所を表すと仮定します)、それらを相互に独立して変更または取得できないようにする必要があります。つまり、各値にセッターとゲッターを追加するのではなく、その両方にセッターとゲッターを追加するべきです。そして、これらの値が一緒に属している場合は、

public class Location { 
    private double mLon; 
    private double mLat; 

    // Add getters and setters. These don't need to be synchronized 
} 

とだけ​​ブロックを使用して、完全を期すため

public static synchronized setLocation(final Location inLocation) { 
    ... 
} 

MainActivityで同期アクセサを変更するように両方の値を表す新しいクラスを導入するのだろうと思うことができ共有状態オブジェクトにスレッド同期を実装する最も一般的ですが最も効率的ではありません。パフォーマンスに関しては、java.util.concurrentのクラスをご覧ください。 Lockオブジェクトの簡単な紹介については、hereを参照してください。

UPDATE

2

最初のコード例で
更新答えは、synchronized static methodsは、Javaの組み込みロックのタイプです。クラスオブジェクトはロックとして使用されるため、一度に1つのスレッドしかクラスで動作できません。あるスレッドがメソッドの1つを実行している場合、他のスレッドはオブジェクトメソッドを実行できません。これは同期のロックタイプです。パフォーマンスに影響します。しかし、高性能が要求されない場合、この解決策は機能します。​​キーワードでデータを読み書きするマークメソッドが必要です。

第2に、私はあなたの変数が位置の座標を意味すると仮定します:緯度と経度。その場合は、一緒にアクセスする必要があります。新しい複合クラスを作ることができます。同時にアクセスされないと、競合状態に陥る可能性があります。

PS:同期は、パフォーマンスに影響を与える場合はお知らせ。クラスレベルのソリューションでは非ロックです。

関連する問題