3

私は、JavaでUDPパケットを読み込んでオブジェクトに入れます(基本的に無限ループ)。このオブジェクトは、複数の別々のスレッドでアクセスされますが、同時に満たされているため、これらのgetter/setterはすべて同期メソッドになっています。問題は今、これらのゲッターは、このようなコードを持って、次のとおりです。Java同期オブジェクト?

public synchronized SomeObject exampleGetter() { 
    if(this.isReceiving) 
     return oldCachedObject; 
    else 
     return currentObject; 
} 

は明らかに、それは物事の非常に最良の方法はありませんので、どのように私は完全にオブジェクトをロック書き込み方法(異なるものの多く)に取り掛かる必要があります一度に1つのスレッドに移動し、他のスレッド(最初にオブジェクトを作成したスレッドを含む)をブロックしますか?私は同期化されたブロックを見ましたが、私はちょっと混乱しています "ロックオブジェクト"が持っている効果は、その時点でブロックにアクセスするオブジェクトですか?アドバイスをいただければ幸いです。ありがとう!

+3

は[実践でのJava並行処理](http://jcip.net/)を見てみましょう。 – ObscureRobot

+1

google 'プロデューサー/コンシューマーin java' –

答えて

5

​​キーワードは、セッターだけでなくオブジェクトインスタンス全体に同期します。私はむしろきめ細かいロック戦略またはそれ以上に行くでしょう...スレッドセーフなデータ構造を使用して、受信したデータを格納して取得します。私は個人的にはBlockingQueue<T>を愛しています。Tは、ネットワーク上で受け取るデータの種類です。

ですから、ソケット経由Object Sを受けているとします

public class ReceivedDataHolder{ 
    BlockingQueue<Object> dataBuffer = new LinkedBlockingQueue<Object>(); 
    //... 
    public void dataReceived(Object data){ 
     dataBuffer.offer(data); 
    } 

    public Object getReceivedData(){ 
     return dataBuffer.take(); 
    } 
} 

そして、あなたがデータを受信するたびに、あなたのソケットに、あなたはこれを行うことができます:

receivedDataHolder.dataReceived(object); 

データを取得したい任意のスレッドがなければなりませんdo:

receivedDataHolder.getReceivedData(); 

この後者のメソッド呼び出しでは、呼び出し元のスレッドunt ILキューで利用可能な要素がある(詳細はthisをチェックアウト)

私はいずれかのスレッドが任意のオブジェクト上の任意の操作をしたい場合は、Javaのすべてのオブジェクトは、組み込みロックと呼ばれるものがあり、これは

+2

'BlockingQueue'はインターフェースなので、' new BlockingQueue (); 'はコンパイルされません。 'ArrayBlockingQueue 'や 'LinkedBlockingQueue 'のようなインターフェイスを実装する具体的なクラスを使用する必要があります。これは、プロデューサ/コンシューマにとって最も一般的に使用される具体的なブロックキューです。 –

+0

@BrunoReis確かに、私の間違いです。 – GETah

0

を役に立てば幸いそのオブジェクトの固有のロックを取得する必要があります。任意の時点で1つのスレッドのみがあなたのブロックを処理することが保証されます。

スレッドは任意のオブジェクトに対してロックを取得できます。オブジェクトが他のスレッドによってロックされていない場合、ロックされている場合、そのスレッドは他のスレッドがそのオブジェクトのロックを解除するまで待機します。

あなたが同期ブロックを使用している場合、あなたのコードはややあなたのスレッドがsynchronizedブロックに入ったときに、他のスレッドがこのオブジェクトのロックを持っている場合、それは待機します。この場合、この

public void SomeObject exampleGetter() { 

synchronized(this) 
{ 


if(this.isReceiving) 
     return oldCachedObject; 
    else 
     return currentObject; 


} 

のようになりますそのスレッドがロックを解除するまでそのオブジェクトが解放されている場合、スレッドはこのオブジェクトのロックを取得して操作を実行し、そのオブジェクトのロックを解放します。 synchronizedブロック、メソッドおよび固有のロックの詳細については

、私はそれはあなたを助けた:)

+3

完全に非意味:* "任意のスレッドが任意のオブジェクトに対して操作を実行したい場合、そのオブジェクトの本来のロックを取得する必要がある" *。どのスレッドも、どのような種類のロックも取得することなく、それが知っているすべてのオブジェクトで何かを行うことができます。 –