转换为ScheduledThreadPoolExecutor

Saa*_*ieh 5 java swing multithreading executorservice event-dispatch-thread

我仍然是Java的初学者,所以我没有学到很多关于线程和并发的知识.但是,我希望能够使用ScheduledThreadPoolExecutor作为计时器,因为我遇到了java.util.Timer和TimerTask的问题.我对线程的创建非常感兴趣,并且知道我将在几周内学习它们.但是,如果有可能,有人可以给我一个基本的例子,说明如何使用util.timer将当前的迷你测试程序转换为使用ScheduledThreadPoolExecutor?

我想尽快完成这个例子,所以我没有太多时间去学习线程 - 不管我想要多少.说完这些之后,请包含您认为Java初学者应该了解的有关ScheduledThreadPoolExecutor的重要信息.

示例程序

我已经做了一个快速的小例子来表示我在一个更大的程序中遇到的问题.该程序应该做的是允许用户按下按钮来启动计数器.然后,用户必须能够在他/她想要时停止并重新启动计数器.在较大的程序中,此计数器保持相等至关重要,因此我使用了scheduleAtFixRate()方法.初始延迟始终相同(在这种情况下为0)也很重要.问题(我相信你会看到)是一旦取消定时器就无法重启 - 我希望ScheduledThreadPoolExecutor能解决这个问题.

码:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我经常使用这个类进行测试,因此可能会有额外的代码(我想我已将其全部删除).

Pet*_*rey 23

更换

Timer timer = new Timer();
Run Code Online (Sandbox Code Playgroud)

ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
Run Code Online (Sandbox Code Playgroud)

class Task extends TimerTask
Run Code Online (Sandbox Code Playgroud)

class Task implements Runnable
Run Code Online (Sandbox Code Playgroud)

timer.scheduleAtFixedRate(new Task(), 0, 1000);
Run Code Online (Sandbox Code Playgroud)

service.scheduleAtFixedRate(new Task(), 0, 1000, TimeUnit.MILLISECONDS);
Run Code Online (Sandbox Code Playgroud)

顺便说一句您不应该尝试在另一个线程上更新GUI.相反,您必须向Swing GUI线程添加任务以执行任务

    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            textOut.setText("" + i++);
        }
    });
Run Code Online (Sandbox Code Playgroud)