0

当我启动我的 GUI 界面时,如果我不使用 invokeLater 会发生什么?

  1. 这是否意味着所有其余的 GUI 绘画/更新/等。会在主线程中吗?
  2. 调用repaint外部的 ainvokeLater会使所有后续调用都落入主线程吗?

基本上是这样的:


void main()
{
    JFrame jmf();
    setVisible(jmf);
}

------------- VS -------------

void main()
{
    SwingUtilities.invokeLater(new Runnable(){
       run(){
          JFrame jmf();
          setVisible(jmf);
       }
    }
});

注意:在小 GUI 的情况下,如果我不放invokeLater它似乎可以正常工作。事实上,尽管main执行了最后一行,但应用程序并没有终止。

我已经阅读了很多关于为什么我们应该使用它的文章,这些文章与 Swing 不是线程安全的(它是单线程的等等)有关,但我真的没有读过不调用的后果invokeLater(部分是因为我的线程知识有限)

4

1 回答 1

4

现实是,什么都不会发生,否则世界就会终结。几乎不可能断言,这是多线程环境的本质......

除非您正在进行一些真正动态的设置,否则在 a 帧可见之前,“应该”不要在 EDT 的上下文中执行它。

问题归结为不同平台的实现方式不同(在本机级别)。例如,在启动 UI 时使用 invokeLater 的原始要求似乎来自多年前 Sun OS 上的死锁。

我也看到了 Java 7 的一些问题(但至少可以说我的前辈对线程的想法很奇怪)。一般建议是,使用 invokeLater 创建和显示您的 UI。在 EDT 的上下文中运行所有 UI 代码

它还将降低您不得不花费数周时间尝试复制和追踪这些奇怪异常的风险(通过在 EDT 中运行您所有的 UI 代码)

根据 OP 的评论更新

repaint向 提出请求,该请求RepaintManager决定应该绘制什么以及何时绘制。它实际上会将“绘制”事件直接发布到事件队列上,然后由事件调度线程处理,因此重绘实际上是在(少数)线程安全方法上......

看一眼

一般的建议是,你应该使用invokeLater,因为这就是 API 的设计方式,做任何其他事情都会引发问题......

于 2013-11-30T00:07:18.890 回答