2

我正在编写一个 GUI 来显示来自客户的传入请求。服务器填充 a LinkedBlockingQueue,而当有可用数据时,另一个线程从队列中取出。请求存储为Object. 像这样:

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

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

现在我的问题来了,最好是:

解决方案1:

将 key 作为请求的哈希值,将 value 作为 Object存储request在 a中。ConcurrentHashMap<Integer, Object>然后我将使用 aDefaultListModel来存储请求的标识符(例如请求类型)和哈希值。将DefaultListModel用于填充JList,有效地向用户显示请求。然后可以使用保存在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内容DefaultListModelDataHolder并且不需要对任何其他数据结构的引用来检索实际的请求值。因为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),哪个解决方案执行得更快?

4

1 回答 1

2

解决方案3:扩展SwingWorker

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

在您的实现中doInBackground()publish()中间结果可用时。在您的 实现中process(),更新视图组件的模型。方便地,将以可持续的速度SwingWorker合并publish()调用。分析您的应用程序以进行验证。更多示例可在此处找到。

于 2014-03-25T13:10:22.677 回答