Хранение данных в DefaultListModel vs ConcurrentHashMap


Я пишу графический интерфейс в swing для отображения несогласованных запросов от клиентов. Сервер заполняет LinkedBlockingQueue, в то время как другой поток берет из очереди, когда есть доступные данные. Запросы хранятся в виде Object. Вот так:

while(should_take) {
    //getRequest() is blocking
    Object request = server.getRequest();

    //Add request to user interface
    GUI.addToList(request);
}

Теперь мой вопрос, не лучше ли было бы:

Решение 1:

Храните request в ConcurrentHashMap<Integer, Object> с ключом в качестве хэша запроса и значением в качестве объекта. Затем я буду использовать a DefaultListModel для хранения идентификатор (напр. тип запроса) запроса и хэш-значения. DefaultListModel будет использоваться для заполнения JList, эффективно отображая запрос пользователю. Значение запросаselected (выбранного пользователем) затем может быть извлечено из ConcurrentHashMap с помощью хэша, сохраненного в DefaultListModel.

Пример кода:

ConcurrentHashMap<Integer, Object> requests = new ConcurrentHashMap<>();
DefaultListModel listData = new DefaultListModel();
JList theList = new JList();
...
public void addToList(Object request) {
    //Place in HashMap
    requests.put(request.hashCode(), request);

    //Create a DataHolder with the Hashvalue and identifier of the request
    DataHolder holder = new DataHolder(request.getID(), request.hash);

    //Add the element to the ListModel
    listData.addElement(holder);

    //Assign the list model to the JList
    theList.setModel(listData);
}

Когда пользователь выбирает элемент в списке:

DataHolder holder = (DataHolder)theList.getSelectedValue();
//Get request from HashMap

Object request = requests.get(holder.getHash());
//Do something with request

Решение 2:

Я заполняю новый объект, назовите его DataHolder, с идентификатором запроса и значением запроса. Теперь я могу заполнить JList с DefaultListModel, который содержит DataHolder, и никакая ссылка не требуется на любую другую структуру данных, чтобы получить фактическое значение запроса. Поскольку DefaultListModel используется для заполнения JList, я чувствую, что это может повлиять на производительность и может привести к тому, что список будет заполняться/не заполняться медленнее.

Пример кода:

DefaultListModel listData = new DefaultListModel();
JList theList = new JList();
...
public void addToList(Object request) {
    //Removed HashMap

    //Create a DataHolder with the Hashvalue and *actual value* of the request
    DataHolder holder = new DataHolder(request.getID(), request);

    //Add the element to the ListModel
    listData.addElement(holder);

    //Assign the list model to the JList
    theList.setModel(listData);
}

Когда пользователь выбирает элемент в списке:

//No more HashMap
DataHolder holder = (DataHolder)theList.getSelectedValue();

Object request = holder.getData();
//Do something with request

Какое решение будет дать более быстрые результаты? Есть ли более эффективный способ сделать это? Любая помощь в этом вопросе будет очень признательна.

Еще немного информации:

    Запрос может подаваться в виде пакетов. (50+ за серию)
  • запросы будут состоять из 20-50 строк XML
  • запросы будут удалены из структуры данных случайным образом

Правка:

Последовательность, добавляющая сообщения в список, теперь обернута в invokeLater. С моей реализацией, каждый раз, когда сообщение будет добавлено в список, будет создан новый поток, который выполнит всю работу и завершится, как только сообщение окажется в списке. Конечно, это влияет на ответ. Если 50 потоков создаются в плотной последовательности (с каждым вызовом addToList), какое решение будет выполняться быстрее?
1 2

1 ответ:

Решение 3: Расширить SwingWorker,

class MessageWorker extends SwingWorker<List<DataHolder>, DataHolder> {}

В вашей реализации doInBackground(), publish() промежуточные результаты по мере их появления. При реализации process(), обновление модели представления компонента. Удобно, что SwingWorker будет объединять publish() вызовы в устойчивом темпе. профиль ваше приложение для проверки. Другие примеры можно найти здесь.