在EDT中运行代码的正确方法是什么?

Yup*_*ing 4 java swing event-dispatch-thread

我有一个Swing应用程序,它使用Java Thread来不断执行某些操作.此操作的结果更新UI中图形的内容:

class ExampleThread {
    ... 
    public void run() {
        while (running) {
            // extract some information
            ...

            // show results in UI
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                     // use information to update a graph
                }
            });

            // sleep some seconds
            ...
        }
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是当EDT在其他操作中膨胀时.在这种情况下,ExampleThread可以注册Runnable更新图形的各种实例.对于我的应用程序,由于图表将在显示结果之前多次更新,因此将浪费时间.我想要的是//update a graph每个EDT周期最多运行一次代码.

我的问题是:确保a Runnable只运行一次的正确方法是什么?

Sco*_*ler 5

原子脏标志应该可以解决问题.这具有额外的好处,即只在必要时才添加到EDT队列.大的假设 - 保存提取的信息的数据结构是线程安全的,但是对于上面的代码来说,这也必须是正确的.如果不是,您应该考虑另一个答案中指出的SwingWorker方法; 您还可以与脏标志结合使用以防止冗余更新.

AtomicBoolean dirty = new AtomicBoolean(false);
while (running) {
        // extract some information
        ...

        if (!dirty.getAndSet(true)) {            
          SwingUtilities.invokeLater(new Runnable() {
              public void run() {
                if (dirty.getAndSet(false)) {
                   // use information to update a graph
                }
              }
          });
        }

        // sleep some seconds
        ...
    }
Run Code Online (Sandbox Code Playgroud)