5

私はまだ Java の初心者なので、スレッドと並行性についてはあまり学んでいません。ただし、java.util.Timer と TimerTask に問題があるため、ScheduledThreadPoolExecutor をタイマーとして使用できるようにしたいと考えています。私はスレッドの作成に非常に興味を持っており、数週間後にそれらについて学習することを知っています. ただし、可能であれば、現在のミニ テスト プログラムを util.timer を使用して ScheduledThreadPoolExecutor を使用するように変換する方法の基本的な例を教えてもらえますか?

この例をできるだけ早く完成させたいので、スレッドについて学ぶ時間があまりありません。とは言っても、ScheduledThreadPoolExecutor に関して Java 初心者が知っておくべき重要なことは何でも含めてください。

プログラム例

大規模なプログラムで発生している問題を表す簡単な小さな例を作成しました。このプログラムがすべきことは、ユーザーがボタンを押してカウンターを開始できるようにすることです。ユーザーは、必要なときにいつでもカウンターを停止および再開できる必要があります。大規模なプログラムでは、このカウンターが等しいことが重要であるため、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);
    }
}

私はこのクラスをテストによく使用するため、余分なコードが含まれている可能性があります (すべて削除したと思います)。

4

1 に答える 1

23

交換

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 スレッドにタスクを追加してタスクを実行する必要があります

    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            textOut.setText("" + i++);
        }
    });
于 2013-01-14T08:50:14.743 に答える