2

クライアントからの着信要求を表示するための GUI をスイングで作成しています。サーバーLinkedBlockingQueueは にデータを取り込みますが、利用可能なデータがある場合、別のスレッドがキューから取得します。リクエストは として保存されますObject。そのようです:

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

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

今、私の質問が来ました。

解決策 1:

キーをリクエストのハッシュとして、値をオブジェクトとして に格納しますrequest。次に、aをConcurrentHashMap<Integer, Object>使用して、リクエストの識別子(リクエスト タイプなど) とハッシュ値を格納します。は、にデータを入力するために使用され、リクエストを効果的にユーザーに表示します。選択されたリクエスト (ユーザーによって選択された)の値は、に保存されたハッシュを使用して ConcurrentHashMap から取得できます。DefaultListModelDefaultListModelJListDefaultListModel

いくつかのコード例:

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。私の実装では、メッセージがリストに追加されるたびに、すべての作業を行う新しいスレッドが作成され、メッセージがリストに追加されると終了します。確かにこれは答えに影響します。(addToList を呼び出すたびに) 50 個のスレッドが連続して作成された場合、どのソリューションがより速く実行されますか?

4

1 に答える 1

2

解決策 3: 拡張SwingWorker,

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

の実装ではdoInBackground()publish()利用可能になったときの中間結果。の実装でprocess()、ビュー コンポーネントのモデルを更新します。便利なことに、持続可能なペースで呼び出しSwingWorkerを合体させます。アプリケーションをプロファイリングして検証します。その他の例については、こちらを参照してください。publish()

于 2014-03-25T13:10:22.677 に答える