3

面白い状況を見つけました。あなたがSwingWorkerを持っているとしましょう(私はこれを漠然と自分のものを彷彿とさせます):

public class AddressTreeBuildingWorker extends SwingWorker<Void, NodePair> {
    private DefaultTreeModel model;
    public AddressTreeBuildingWorker(DefaultTreeModel model) {
    }

    @Override
    protected Void doInBackground() {
        // Omitted; performs variable processing to build a tree of address nodes.
    }

    @Override
    protected void process(List<NodePair> chunks) {
        for (NodePair pair : chunks) {
            // Actually the real thing inserts in order.
            model.insertNodeInto(parent, child, parent.getChildCount());
        }
    }

    private static class NodePair {
        private final DefaultMutableTreeNode parent;
        private final DefaultMutableTreeNode child;
        private NodePair(DefaultMutableTreeNode parent, DefaultMutableTreeNode child) {
            this.parent = parent;
            this.child = child;
        }
    }
}

バックグラウンドで行われた作業が重要である場合、物事はうまく機能します-process()オブジェクトの比較的小さなリストで呼び出され、すべてが幸せです。

問題は、バックグラウンドで行われた作業が何らかの理由で突然重要でなくなった場合、process()オブジェクトの膨大なリスト(たとえば、1,000,000を見た)を受け取り、各オブジェクトを処理するまでに、イベントディスパッチに20秒を費やしたことです。スレッド、まさにSwingWorkerが回避するように設計されたもの。

はっきりしない場合は、これらの両方が私にとって同じSwingWorkerクラスで発生します。これは、入力データと、呼び出し元が必要とする処理のタイプによって異なります。

これを処理する適切な方法はありますか?もちろん、バックグラウンド処理スレッドを意図的に遅らせたり、譲ったりして、毎回少ない数到着するようにすることはできますが、これは私にとって正しい解決策とは思えません。

4

2 に答える 2

4

結果の小さなチャンクを公開してみることができます。

それでも問題が解決しない場合は、計算の代わりにUIの更新を調整することを検討してください。process受信したNodePairsをブロッキングキューに保存することで、UIの更新をモデレートできます。

@Override
protected Void doInBackground() {
    this.treeModelUpdater.execute();
    // Omitted; performs variable processing to build a tree of address nodes.
}

@Override
protected void process(List<NodePair> chunks) {
    this.queue.addAll( chunks ); // a blocking queue
}

@Override
protected void done() {
    // Null Object as sentinel value to unblock TreeModelUpdater
    // and signal it to end doInBackground.
    this.queue.put( new NullNodePair() );
}

TreeModelUpdater( )は、そのメソッドが抑制された方法でキューからNodePairsを取得して公開this.treeModelUpdaterする従属SwingWorker実装になります。 doInBackground

于 2010-05-28T02:20:06.137 に答える
2

私の知る限り、プロセス方法は主にバックグラウンド処理の結果でUIを更新することです。1Mioチャンクの場合、そのすべての情報が画面のどこに表示されるのでしょうか。:-)

チャンクを大きなリストにまとめて送信し、処理のために送信して、少なくとも同期部分が大幅に削減されるようにします。

コントロールを使用して1Mioデータ要素を表示できるようにする必要がある場合は、遅延表現手法を使用しない限り、つまり実際に表示されているものだけをインスタンス化しない限り、パフォーマンスが低下します。この場合、プロセスルーチンはオーバーロードされなくなります。

于 2010-05-28T01:30:31.720 に答える