2011-11-11 12 views
2

私のアプリケーションには、マスターのコールオーバーソケットに応答し、統計をオブジェクトに送信するマスターと多くのスレーブがあります。今、私は1つのマスターと2つの奴隷でコードをテストしています。コードは1スレーブで正常に動作しますが、2スレーブでは、マスター側で受け取ったオブジェクトに2回、つまり同じオブジェクトの2つのコピーが作成されます。シリアル化中の競合状態

メーザーのコード:マスターはスレーブから定期的に受け取り、したがって、タイマーを使用してexceuting:

public void run() { 

    try { 
     byte[] recvBuf = new byte[15000]; 
     DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length); 
     DatagramSocket dSock = new DatagramSocket(4445); 
     dSock.receive(packet); 
     int byteCount = packet.getLength(); 
     ByteArrayInputStream byteStream = new ByteArrayInputStream(recvBuf); 
     ObjectInputStream is = new ObjectInputStream(new BufferedInputStream(byteStream)); 
     //receiving the object pm of class PM 
     pm1=(PM)is.readObject(); 
     } 
} 

とスレーブのコード:

{ 
InetAddress address = InetAddress.getByName("10.129.54.254"); 
      ByteArrayOutputStream byteStream = new ByteArrayOutputStream(15000); 
      os = new ObjectOutputStream(new BufferedOutputStream(byteStream)); 
      os.flush(); 
      //sending the object pm of class PM 
      os.writeObject((PM)pm); 
      os.flush(); 
      byte[] sendBuf = byteStream.toByteArray(); 
      DatagramPacket packet = new DatagramPacket(sendBuf, sendBuf.length, address, 4445); 
      int byteCount = packet.getLength(); 
      DatagramSocket dSock = new DatagramSocket(); 
      dSock.send(packet); 
      os.close(); 
      dSock.close(); 
      } 
     } 

・ダウト: 1.私はからオブジェクトを格納すべきアレイの2つの奴隷?もしそうなら、同じオブジェクトが2回保存されないように、ソケット上で受け取った2つのオブジェクトをどうやって区別するのですか?送られたオブジェクトがidのようなユニークな属性を持っていると仮定します。

class PM{ 
int uniqueid; 
} 
  1. つまり私は、全体のコードを書くしようとしているので、ジニまたは他のAPIを使用する必要はありません。 ありがとう!第2のスレーブからの次のオブジェクトは、また、そのフィールドに配置されるよう
+0

どのオブジェクトが送信されていますか?どのようにそれらを保存していますか? – Kane

+0

クラスPMのオブジェクトpmがスレーブ側で送信されています。 PMオブ​​ジェクトの配列を使用してマスター側に保存しています。私はあなたの質問に答えましたか? –

答えて

3

あなたは

 //receiving the object pm of class PM 
    pm1=(PM)is.readObject(); 

を受け取るだけのフィールドに保管しないでください。

代わりに、ローカル変数を使用してオブジェクトの内容を読み取り、それに対処する必要があります。または、別のスレッドで処理する場合は、単一のスレッドExecutorServiceにタスクを追加してオブジェクトを処理します。

+0

@ PeterLawrey-ありがとう!1つの実行のためにそれを試してみました。しかし、私はマスタープログラムを2秒ごとにタイムド・タスクとして実行しています。そして、クライアントの側からのオブジェクトが常に同じ内容を含むとは限りません。 –