Quantcast
Channel: Scratch Where It's Itching
Viewing all articles
Browse latest Browse all 73

When is a SwingWorker really done?

$
0
0
Imagine you have a SwingWorker running, and you would like to know if it has terminated its job. You notice that it has a isDone() method, and say to yourself: "great! I can use it!". But are you sure you know what it is really doing? Are you sure that all your work will be over when it returns 'true'? You would say: "of course, it is called isDone". Well, let's have a closer look.

When you create a SwingWorker, it creates a Callable, and wraps it in a Future:

        Callable callable =                new Callable() {                    public T call() throws Exception {                        setState(StateValue.STARTED);                        return doInBackground();                    }                };        future = new FutureTask(callable) {                       @Override                       protected void done() {                           doneEDT();                           setState(StateValue.DONE);                       }                   };

The Future will be executed by a ThreadPool (of maximum 10 threads). The doInBakground() is called, returning a value that will be used by the Future for its set() method. From this point onwards, calling the isDone() method will yield true. And this is even before the Future's done() method is called. So isDone() only means that doInBackground() terminated. Not what I was thinking.

OK, so why not use the getState() method. I see clearly that it is called by the Future right after the call to doneEDT(). But let's have a look at the doneEDT() method:

    private void doneEDT() {        Runnable doDone =            new Runnable() {                public void run() {                    done();                }            };        if (SwingUtilities.isEventDispatchThread()) {            doDone.run();        } else {            doSubmit.add(doDone);        }    }

As you can see, if we are already in the EDT, we execute immediately the method. But we know that we are started from a ThreadPool, so this is not the case. The doSubmit, surprisingly, uses a Timer and schedules the task in 30ms. Not a SwingUtilities.invokeLater() as I expected, but the result is the same: the getState() will return DONE before we even start the done() method. The PropertyChange are notifying you of the state change. So basically, you are left to yourself.


Viewing all articles
Browse latest Browse all 73

Trending Articles