シリアライズ中の競合状態

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

Maserのコード:マスターは定期的にスレーブから受信し、したがってタイマーを使用して終了します:

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. コード全体を記述しようとしているため、Jiniやその他のAPIを使用したくないです。 ありがとう!
2
クラスPMのオブジェクトpmがスレーブ側で送信されています。 PMオブ​​ジェクトの配列を使用してマスター側に保存しています。私はあなたの質問に答えましたか?
追加された 著者 P R,
どんなオブジェクトが送信されていますか?どのようにそれらを保存していますか?
追加された 著者 Kane,

1 答え

あなたが受け取ったとき

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

2番目のスレーブからの次のオブジェクトもそのフィールドに配置されるため、フィールドに格納しないでください。

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

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