【问题标题】:Java API "Run on EDT if not on EDT"Java API“如果不在 EDT 上,则在 EDT 上运行”
【发布时间】:2012-04-05 10:52:41
【问题描述】:

只是对我的一些重复代码的思考:

Runnable run = new Runnable() {
  @Override
  public void run() {
    // Some EDT code
  }
};

if (!EventQueue.isDispatchThread()) {
  SwingUtilities.invokeAndWait(run);
} else {
  run.run();
}

这不是很烦人,但似乎有一些专有功能会为你检查这个,虽然我还没有找到它。

【问题讨论】:

  • 制作自己的实用程序方法有什么问题,它接受Runnable 并在正确的Thread 上执行它。为您节省 if-else 构造。避免Runnable 会很困难
  • 没错,一切都在 API 中,请使用SSCCE 编辑您的问题,感谢down_voting,看起来就像您在之前的问题中一样黑暗:-)
  • @mKorbel,我不相信您在我之前的问题中给出的答案是正确的。时间不会改变这个事实,在这里提出它只是垃圾邮件。罗宾,这就是我现在正在做的事情,只是看起来有点傻。
  • @Whired right seems a bit silly is all 在这里查看我的答案
  • 这也困扰着我。如果他们要费心在invokeAndWait() 中添加检查,为什么不直接为我们调用runnable.run() 而不是抛出异常?

标签: java swing event-dispatch-thread eventqueue invokeandwait


【解决方案1】:

似乎会有一些专有功能为您检查此内容

没有。

【讨论】:

    【解决方案2】:

    排除物质外观和感觉我从来不需要使用invokeAndWait 或测试isDispatchThread / isEventDispatchThread

    在某些特殊情况下需要物质外观和感觉 invokeAndWait 用于 JTableJTreeSwingX's TreeTable,在这种情况下真的不重要

    “EDT 过期”需要延迟 30 秒,然后您可以创建 n_Threads,然后每个线程都可以存活 EDT,简单,无需特别努力,另一个限制可能是来自 Native OS 的延迟

    输出

    run:
                             Time at : 00:00:45
    There isn't Live EventQueue.isDispatchThread, why any reason for that 
    There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 
    
                             Time at : 00:00:45
    EventQueue.isDispatchThread
    SwingUtilities.isEventDispatchThread
    
                             Time at : 00:00:45
    EventQueue.isDispatchThread
    SwingUtilities.isEventDispatchThread
    
                             Time at : 00:01:15
    There isn't Live EventQueue.isDispatchThread, why any reason for that 
    There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 
    
    Push a new event to EDT
                             Time at : 00:01:45
    EventQueue.isDispatchThread
    SwingUtilities.isEventDispatchThread
    
                             Time at : 00:02:15
    There isn't Live EventQueue.isDispatchThread, why any reason for that 
    There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 
    
                             Time at : 00:02:45
    There isn't Live EventQueue.isDispatchThread, why any reason for that 
    There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 
    
    Push a new event to EDT
                             Time at : 00:03:15
    EventQueue.isDispatchThread
    SwingUtilities.isEventDispatchThread
    
                             Time at : 00:03:45
    There isn't Live EventQueue.isDispatchThread, why any reason for that 
    There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 
    
                             Time at : 00:04:15
    There isn't Live EventQueue.isDispatchThread, why any reason for that 
    There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 
    
    Push a new event to EDT
                             Time at : 00:04:45
    EventQueue.isDispatchThread
    SwingUtilities.isEventDispatchThread
    
    Terminating this madness
    BUILD SUCCESSFUL (total time: 4 minutes 31 seconds)
    

    来自

    import java.awt.EventQueue;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.concurrent.*;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.*;
    
    public class IsThereEDT {
    
        private ScheduledExecutorService scheduler;
        private AccurateScheduledRunnable periodic;
        private ScheduledFuture<?> periodicMonitor;
        private int taskPeriod = 30;
        private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        private Date dateRun;
        private JFrame frame1 = new JFrame("Frame 1");
    
        public IsThereEDT() {
            scheduler = Executors.newSingleThreadScheduledExecutor();
            periodic = new AccurateScheduledRunnable() {
    
                private final int ALLOWED_TARDINESS = 200;
                private int countRun = 0;
                private int countCalled = 0;
                private int maxCalled = 10;
    
                @Override
                public void run() {
                    countCalled++;
                    if (countCalled < maxCalled) {
                        if (countCalled % 3 == 0) {
                            SwingUtilities.invokeLater(new Runnable() {
    
                                @Override
                                public void run() {
                                    System.out.println("Push a new event to EDT");
                                    frame1.repaint();
                                    isThereReallyEDT();
                                }
                            });
                        } else {
                            if (this.getExecutionTime() < ALLOWED_TARDINESS) {
                                countRun++;
                                isThereReallyEDT(); // non on EDT
                            }
                        }
                    } else {
                        System.out.println("Terminating this madness");
                        System.exit(0);
                    }
                }
            };
            periodicMonitor = scheduler.scheduleAtFixedRate(periodic, 0, taskPeriod, TimeUnit.SECONDS);
            periodic.setThreadMonitor(periodicMonitor);
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    isThereReallyEDT();
                    frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame1.getContentPane().add(new JLabel("Hello in frame 1"));
                    frame1.pack();
                    frame1.setLocation(100, 100);
                    frame1.setVisible(true);
                }
            });
            try {
                Thread.sleep(500);
            } catch (InterruptedException ex) {
                Logger.getLogger(IsThereEDT.class.getName()).log(Level.SEVERE, null, ex);
            }
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    JFrame frame2 = new JFrame("Frame 2");
                    frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame2.getContentPane().add(new JLabel("Hello in frame 2"));
                    frame2.pack();
                    frame2.setLocation(200, 200);
                    frame2.setVisible(true);
                    isThereReallyEDT();
                }
            });
        }
    
        private void isThereReallyEDT() {
            dateRun = new java.util.Date();
            System.out.println("                         Time at : " + sdf.format(dateRun));
            if (EventQueue.isDispatchThread()) {
                System.out.println("EventQueue.isDispatchThread");
            } else {
                System.out.println("There isn't Live EventQueue.isDispatchThread, why any reason for that ");
            }
            if (SwingUtilities.isEventDispatchThread()) {
                System.out.println("SwingUtilities.isEventDispatchThread");
            } else {
                System.out.println("There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that ");
            }
            System.out.println();
        }
    
        public static void main(String[] args) {
            IsThereEDT isdt = new IsThereEDT();
        }
    }
    
    abstract class AccurateScheduledRunnable implements Runnable {
    
        private ScheduledFuture<?> thisThreadsMonitor;
    
        public void setThreadMonitor(ScheduledFuture<?> monitor) {
            this.thisThreadsMonitor = monitor;
        }
    
        protected long getExecutionTime() {
            long delay = -1 * thisThreadsMonitor.getDelay(TimeUnit.MILLISECONDS);
            return delay;
        }
    }
    

    你可以做任何事情,改变订单,方法,通过Thread.sleep(int) 冻结,在所有情况下都可以在假定的时刻活着 EDT,没有任何阴影,任何奇迹,调用天堂而不是 EDT 的错误代码

    【讨论】:

    • 我不确定我是否理解您的示例的重点。当调用repaint() 时,EDT 将调用paint(),而不是isThereReallyEDT()。我不担心在使用它的调用之后 EDT 仍然存在,我只是有其他依赖于任务完成的事情要做,但不应该(总是)必须从 EDT 调用。跨度>
    • @Whired 如果 EDT 为空 .... 并且所有输出都在相关 API 中完成,包括向 GUI 的潜在输出(向 GUI 的输出不是条件)然后 EDT 处于非活动状态并返回 @ 987654333@,你可以用例如替换repaint(),paint() pack()、添加/删除 JComponent(s)、setText、Backgound/Foregroung、borders....
    【解决方案3】:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2014-04-14
    • 1970-01-01
    • 2014-01-21
    • 1970-01-01
    相关资源
    最近更新 更多