I just found an interesting situation. Suppose you have some SwingWorker (I've made this one vaguely reminiscent of my own):
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;
}
}
}
If the work done in the background is significant then things work well - process()
is called with relatively small lists of objects and everything is happy.
Problem is, if the work done in the background is suddenly insignificant for whatever reason, process()
receives a huge list of objects (I have seen 1,000,000, for instance) and by the time you process each object, you have spent 20 seconds on the Event Dispatch Thread, exactly what SwingWorker was designed to avoid.
In case it isn't clear, both of these occur on the same SwingWorker class for me - it depends on the input data, and the type of processing the caller wanted.
Is there a proper way to handle this? Obviously I can intentionally delay or yield the background processing thread so that a smaller number might arrive each time, but this doesn't feel like the right solution to me.