转换为ScheduledThreadPoolExecutor

我仍然是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); } } 

我经常使用这个类进行测试,因此可能会有额外的代码(我想我已经删除了所有代码)。

更换

 Timer timer = new Timer(); 

 ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); 

 class Task extends TimerTask 

 class Task implements Runnable 

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

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

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

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