Search code examples
javamultithreadingtimerwhile-loopswingworker

java.util.Timer or a While loop in a SwingWorker thread?


In another question I posted recently I was suggested to use a java.util.Timer in the SwingWorker instead of a while loop. The tasks in the SwingWorker are supposed to run every 10 seconds.

From my understanding, java.util.Timer creates a background thread (run()) to perform tasks.

If I use the java.util.Timer in the SwingWorker thread, isn't it inefficient to create another thread (Timer) in a thread (SwingWorker)?

Please take a look at my two examples below and let me know which one is the correct one, or if none of the two are correct what else I should use (and please provide me with a short sample code if possible)? Thank you

Example 1 - using java.util.Timer

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.SwingWorker;

public class Example1 extends SwingWorker<Void, String> {

    @Override
    protected Void doInBackground() {

        int delay = 10000;//Delay for 10 seconds

        Timer timer = new Timer();

        timer.schedule(new TimerTask() {
            @Override
            public void run() {

                String database = "";

                //PARSE THE SQL DATABASE

                publish(database);//UPDATE THE GUI

            }
        }, delay);

        return null;
    }

    @Override
    protected void process(List<String> s) {
        //UPDATE THE GUI
    }
}

Example 2 - using While loop

import java.util.List;
import javax.swing.SwingWorker;

public class Example2 extends SwingWorker<Void, String> {

    @Override
    protected Void doInBackground() {

        while (!this.isCancelled()) {

            String database = "";

            //PARSE THE SQL DATABASE

            publish(database);//UPDATE THE GUI

            try {
                synchronized (this) {
                    this.wait(10000);//Wait 10 seconds
                }
            } catch (Exception ex) {
            }

        }

        return null;
    }

    @Override
    protected void process(List<String> s) {
        //UPDATE THE GUI
    }
}

Solution

  • If the only thing that SwingWorker is doing is to launch a timer then it's useless indeed. Just spawn the timer from the UI thread and use SwingUtilities.InvokeLater to update the GUI from the timer.

    An even better alternative is ScheduledThreadPoolExecutor.