我正在编写一个GUI,以显示来自客户端的传入请求。服务器填充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>
中,其键为请求的哈希,值为Object。然后,我将使用DefaultListModel
存储请求的标识符(例如请求类型)和哈希值。 DefaultListModel
将用于填充JList
,有效地向用户显示请求。然后,可以使用保存在DefaultListModel
中的哈希从ConcurrentHashMap中检索所选请求的值(由用户选择)。一些示例代码:
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),哪种解决方案将更快执行? 最佳答案
解决方案3:扩展SwingWorker
,
class MessageWorker extends SwingWorker<List<DataHolder>, DataHolder> {}
在
doInBackground()
的实现中,publish()
中间结果可用。在process()
的实现中,更新视图组件的模型。方便地,SwingWorker
将在sustainable pace处合并publish()
调用。 Profile您的应用程序进行验证。可以找到更多示例here。