Состояние гонки во время сериализации

#java #serialization

#java #сериализация

Вопрос:

В моем приложении есть главный сервер и множество подчиненных устройств, которые реагируют на сокеты вызова главного сервера и отправляют статистику в объекте. Прямо сейчас я тестирую код с одним ведущим и двумя подчиненными устройствами. Код отлично работает с 1 подчиненным устройством, но с 2 подчиненными устройствами объекты, полученные на стороне ведущего устройства, заполняются дважды, т. е. Две копии одного и того же объекта.

Код Мазера: ведущее устройство периодически получает данные от подчиненных устройств и, следовательно, завершает работу с использованием таймера:

 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. Должен ли я хранить объекты из двух подчиненных устройств в массиве? Если да, то как мне провести различие между двумя полученными объектами через сокет, чтобы один и тот же объект не сохранялся дважды? Предполагается, что передаваемый объект имеет уникальный атрибут, такой как id.
ie

 class PM{
int uniqueid;
}
  
  1. Я пытаюсь написать весь код и, следовательно, не хочу использовать Jini или другие API.
    Спасибо!

Комментарии:

1. Какие объекты отправляются? Как вы их сохраняете?

2. Объект pm класса PM отправляется на стороне ведомого устройства. Я сохраняю их на стороне мастера, используя массив объектов PM. Я ответил на ваш вопрос?

Ответ №1:

Когда вы получаете

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

Не просто сохраняйте это в поле, поскольку следующий объект из второго подчиненного устройства также будет помещен в эти поля.

Вместо этого вы должны использовать локальную переменную, прочитать содержимое объекта и действовать с ним. Или, если вы хотите, чтобы его обрабатывал другой поток, добавьте задачу в однопоточный ExecutorService для обработки объектов.

Комментарии:

1. @PeterLawrey- Спасибо! Попробовал это для одного запуска. Но я запускаю основную программу как временную задачу каждые 2 секунды. И объект со стороны клиента не всегда содержит одинаковое содержимое.