java - 每 x 次调用函数而不阻塞 GUI Java

标签 java multithreading observable

我有一个名为 ItemGUI 的类,它处理与用户界面相关的所有内容。用户能够添加一些链接,这些链接是项目,因此当他插入链接并单击“添加”按钮时,它应该创建一个 Item 类的新对象并开始运行一个名为 getPrice() 的函数,类似于那:

Item newItem = new Item(newItemField.getText());
// should also be added to a list of items which should be in the ItemGUI class
newItem.getPrice()

这应该在单击添加按钮后完成。然后我将该项目打印到 table 上。问题是 getPrice() 方法应该每 5 秒运行一次,而不会阻塞我的 GUI,所以我应该实现线程。

我的问题是:如何实现一个线程,该线程每 5 秒运行一次该函数(针对列表中的每个项目),直到我单击停止按钮?我正在考虑使用带有时钟的观察者可观察类,每 5 秒通知观察者一次。这会是最好的选择吗? 另外,我是否能够从 ItemGUI 类中检索项目变量?

谢谢!

最佳答案

更新

MadProgrammer 建议的最清晰的解决方案是使用 swing Timers ,像这样:

protected javax.swing.Timer refresherTimer = null;
protected void stopRefreshing() {
    if (refresherTimer != null) {
        refresherTimer.stop();
        refresherTimer = null;
    }
}
protected void startRefreshing() {
    stopRefreshing();
    refresherTimer = new Timer(500, e -> {
        newItem.getPrice()
    });
    refresherTimer.start();
}
public void onStartButtonClicked() {
    Item newItem = new Item(newItemField.getText());
    // here newItem should be added to a list of items which should be in the ItemGUI class
    startRefreshing();
}
public void onStopButtonClicked() {
    stopRefreshing();
}

原始答案

如果有一些名为例如的实用程序,那就太好了GuiTimer 这将使您的任务变得简单:

protected GuiThread.Task refresherTask = null;
protected void cancelRefreshing() {
    if (refresherTask != null) {
        refresherTask.cancel();
        refresherTask = null;
    }
}
public void onStartButtonClicked() {
    Item newItem = new Item(newItemField.getText());
    // should also be added to a list of items which should be in the ItemGUI class
    cancelRefreshing();
    refresherTask = GuiThread.scheduleAtFixedRate(() -> {
        newItem.getPrice()
    }, 0, 5, TimeUnit.SECONDS);
}
public void onStopButtonClicked() {
    cancelRefreshing();
}

常规计时器的问题是它们在自己的线程上调用回调函数,而不是在 gui 线程上,因此需要开发人员确保正确的线程。不幸的是,内置的java EventQueue不支持调度延迟任务。

出于这个原因,我喜欢使用以下名为 GuiTimer 的实用程序,它将充当纯 gui 线程计时器:

public class GuiTimer {
    public static final ScheduledThreadPoolExecutor executor = 
            new ScheduledThreadPoolExecutor(1);

    public static interface Task {
        public void cancel();
    }

    private static class CancelStateTask implements Task {
        public volatile boolean canceled = false;

        @Override
        public void cancel() {
            this.canceled = true;
        }
    }

    public static Task schedule(final Runnable action) {
        CancelStateTask task = new CancelStateTask();
        EventQueue.invokeLater(() -> {
            if (!task.canceled)
                action.run();
        });
        return task;
    }

    public static Task schedule(final Runnable command, long delay,
            TimeUnit unit) {
        ScheduledFuture<?> future = executor.schedule(
                () -> EventQueue.invokeLater(command), delay, unit);
        return () -> future.cancel(false);
    }

    public static Task scheduleAtFixedRate(Runnable command,
            long initialDelay, long period, TimeUnit unit) {
        ScheduledFuture<?> future = executor.scheduleAtFixedRate(
                () -> EventQueue.invokeLater(command), initialDelay,
                period, unit);
        return () -> future.cancel(false);
    }

    public static Task scheduleWithFixedDelay(Runnable command,
            long initialDelay, long delay, TimeUnit unit) {
        ScheduledFuture<?> future = executor.scheduleAtFixedRate(
                () -> EventQueue.invokeLater(command), initialDelay, delay,
                unit);
        return () -> future.cancel(false);
    }

    public static void shutdown() {
        executor.shutdown();
    }
}

关于java - 每 x 次调用函数而不阻塞 GUI Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34240070/

相关文章:

java - 解析Java源代码时如何解析标识符的类型?

c - 如何在 Windows 中检索线程的起始地址?

android - 可观察的延迟会忽略设备动画设置

java - 为什么mock方法总是正确的?

java - JSON 中的重复 boolean 字段

java - jPcap - 将数据包发送到选定的 MAC(而不是选定的接口(interface))

java - 在Android中,何时在SurfaceView中创建的线程被销毁?

进程与线程的性能影响

angular - 将参数附加到 Observable 中的嵌套数组

javascript - 遍历可观察数组并更新计算值