#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.