【问题标题】:What if I don't use SwingUtilities.invokeLater?如果我不使用 SwingUtilities.invokeLater 怎么办?
【发布时间】:2013-11-29 23:35:14
【问题描述】:

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

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

基本上是这样的:


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

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

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

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

我已经阅读了很多关于为什么我们应该使用它的文章,这些文章涉及到 Swing 不是线程安全的(它是单线程等等),但我真的没有读过 not 的影响打电话给invokeLater(部分是因为我对线程的了解有限)

【问题讨论】:

  • 这并不总是发生,但您可能会冒着应用程序间歇性失败的风险。这发生在我身上,尤其是在使用一些外观和感觉时。
  • @Hovercraft Full Of Eels 我正在为这个问题添加更多细节。
  • 老实说,除非您正在做一些真正动态的设置,否则在 a 框架可见之前,“应该”不要在 EDT 的上下文中执行此操作。问题归结为不同平台的实现方式不同。例如,在启动 UI 时使用invokeLater 的原始要求似乎来自多年前 Sun OS 的死锁。我还看到了 Java 7 的一些问题。一般建议是,使用 invokeLater 创建和显示您的 UI。在 EDT 的上下文中运行所有 UI 代码
  • repaint() 我相信在 EDT 上排队请求。
  • 只有在为老板或客户演示程序时才会失败。否则它会工作得很好。

标签: java multithreading swing invokelater


【解决方案1】:

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

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

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

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

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

根据 OP 的 cmets 更新

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

看看

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-20
    • 1970-01-01
    • 1970-01-01
    • 2022-06-11
    • 2022-07-25
    • 2013-10-01
    • 1970-01-01
    相关资源
    最近更新 更多