Search code examples
javamultithreadingswingthread-safetyswingworker

Java - using Thread instead of SwingWorker


I cannot really get the advantage of using a swingworker instead of just simply putting the heavy task in a (simple) background-thread.

This is just a codesnippet but shows the task of counting an integer and putting the values in a JLabel. (this is within the ActionPerformed)

Thread t = new Thread() {
    public void run() {
        for (int i = 0; i < 2000000; i++) {
            counter++;
            label.setText(Integer.toString(counter));       
        }
    }
};

t.start();

Instead of this simple codesnippet I have been told to use the abstract SwingWorker-class and override methods such as doInBackground, process and done.

It works very fine when the label is updating simply using Thread. Why should I create a new class that extends swingworker and implement the abstract methods? I can at the moment only think of the Swing-worker as threadsafe, is that the answer?


Solution

  • Swing is not thread safe, modifying the UI outside of the context of the EDT, like you are will, cause random paint artifacts and dirty paint issues which will be near impossible to track down.

    See Concurrency in Swing for more details

    The publish method of the SwingWorker pushes the update onto the a queue, which is processed within the EDT and pushed to the process method. done is also called within the context of the EDT, making it safe to update the UI from

    Now, you could use something like...

    Thread t = new Thread() {
        public void run() {
            int counter = 0 ;
            for (int i = 0; i < 2000000; i++) {
                counter++;
                SwingUtilities.invokeLater(new Runnable() {
    
                    @Override
                    public void run() {
                        label.setText(Integer.toString(counter));
                    }
                });
            }
        }
    };
    
    t.start();
    

    And under Java 8+ you probably won't have to many issues, but Java 6 can be finicky about needing a final variable for anonymous classes, which is why I generally avoid it.

    SwingWoker also has progress support via it's setProgress method and PropertyChangeListener, which is also another way you can provide feedback...