Как ставить в очередь пакеты, полученные при подключении к сокету, для обработки и обновления пользовательского интерфейса в полученном порядке

#java #multithreading #swing #sockets

#java #многопоточность #swing #сокеты

Вопрос:

У меня есть пользовательское приложение, которое считывает данные из сокета и выполняет некоторый синтаксический анализ перед обновлением таблицы. Формат поступающих данных — это несколько строк csv, передаваемых примерно каждую секунду. Моя текущая реализация для моего класса Connection приведена ниже.

handleDetectionEvent() в пользовательском интерфейсе использует рабочий поток для соответствующего анализа строки и соответствующего обновления таблицы. Проблема, с которой я сталкиваюсь, заключается в том, что каждая новая строка генерирует новый рабочий поток, и у меня нет гарантии, что таблица будет обновляться в порядке полученных пакетов, поэтому два обновления для одного и того же элемента в таблице могут привести к тому, что более раннее будет отображаться как последнее обновление. Как я могу предотвратить это?

 public class Connection implements Runnable {

        private Socket socket;
        private BufferedReader bufferedReader;
        DetectionManager manager;

        public Connection(String sIpAddress, int iPortNumber) throws UnknownHostException, IOException{
            socket = new Socket(sIpAddress, iPortNumber);
        }


        public void run(){
                try {
                    String sCurrentLine;
                    bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    while ((sCurrentLine = bufferedReader.readLine()) != null) {                    
                        if (Thread.interrupted()){
                            closeConnection();
                            return;
                        }                           
                        manager.mUI.handleDetectionEvent(sCurrentLine);
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }


        private void closeConnection(){
            try {
                socket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
  

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

1. Вам не нужны никакие рабочие потоки. Вам просто нужен поток, который считывает все из сокета, и когда вы получаете строку, которую вам нужно использовать SwingUtilities.invokeLater для синхронизации с EDT (поток диспетчера событий).

2. Но тогда где выполняется синтаксический анализ?

3. Вы можете создать строку таблицы в своем потоке сокет-коннектор, но добавление в таблицу (модель) должно выполняться в EDT.

4. И если время, затраченное на анализ строки, превышает интервал времени между последовательными строками, появляющимися в сокете, будут ли они автоматически поставлены в очередь, чтобы строки не были потеряны, учитывая текущую реализацию?

5. Я не знаю, может ли сокет буферизировать входные данные. Но если нет, вы можете переместить синтаксический анализ в другой поток (используйте класс java.util.concurrent. Исполнители) и из этого нового потока вы можете уведомить EDT с помощью вызова invokeLater.