Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

converting to ScheduledThreadPoolExecutor

I am still a beginner at Java so I have not learned much about threads and concurrency. However, I would like to be able to use the ScheduledThreadPoolExecutor as a timer because of the problems I am having with java.util.Timer and TimerTask. I am extremely interested in the creation of threads and know that I will be learning about them in a few weeks. However, if possible could someone give me a basic example on how to convert my current mini test program using util.timer to using a ScheduledThreadPoolExecutor?

I would like to complete this example ASAP so I don't have much time to learn about threads - no matter how much I would like to. Having said this please include anything you feel is important that a java beginner should know with regards to ScheduledThreadPoolExecutor.

Example program

I have made a quick small example to represent the problem I am having in a larger program. What this program should do is allow the user to press a button to start a counter. The user must then be able to stop and restart the counter when ever s/he wants. In the larger program it is vital that this counter remains equal so I have used the scheduleAtFixRate() method. It is also important that the initial delay is always the same (in this case 0). The problem (as I am sure you will see) is that once the timer is cancelled it cannot be restarted - something that I hope the ScheduledThreadPoolExecutor will resolve.

code:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.TimerTask;
import java.util.Timer;

public class Tester extends JFrame {
    JButton push = new JButton("Push");
    static JTextArea textOut = new JTextArea();
    Timer timer = new Timer();
    boolean pushed = false;
    static int i = 1;

    public Tester() {
        super();
        add(push, BorderLayout.NORTH);
        add(textOut);
        push.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (!pushed) {
                    timer.scheduleAtFixedRate(new Task(), 0, 1000);
                    pushed = true;
                } else {
                    timer.cancel();
                    pushed = false;
                }
            }
        });
    }

    static class Task extends TimerTask {
        public void run() {
            textOut.setText("" + i++);
        }
    }

    public static void main(String[] args) {
        Tester a = new Tester();
        a.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        a.pack();
        a.setVisible(true);
    }
}

I use this class a lot for testing so there may be extra code (I think I removed it all).

like image 686
Saad Attieh Avatar asked Jan 14 '13 08:01

Saad Attieh


1 Answers

Replace

Timer timer = new Timer();

with

ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

and

class Task extends TimerTask

with

class Task implements Runnable

and

timer.scheduleAtFixedRate(new Task(), 0, 1000);

with

service.scheduleAtFixedRate(new Task(), 0, 1000, TimeUnit.MILLISECONDS);

BTW You should not be attempting to update the GUI on another thread. Instead you have to add a task to the Swing GUI Thread to perform the task

    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            textOut.setText("" + i++);
        }
    });
like image 119
Peter Lawrey Avatar answered Oct 03 '22 23:10

Peter Lawrey