代码之家  ›  专栏  ›  技术社区  ›  ddimitrov

是否允许在非EDT线程中加载Swing类?

  •  8
  • ddimitrov  · 技术社区  · 14 年前

    在引入Java内存模型之后,Swing指南被修改为任何Swing组件都需要在EDT上实例化,以避免出现未发布的实例状态。

    我在任何地方都找不到的是类加载是否也被强制在EDT上,或者我们是否可以在后台线程中预加载键Swing类?Sun/甲骨文对此是否有任何官方声明?是否有已知的类保持非线程安全静态,因此需要加载到EDT上?

    澄清Nemi的问题: 这是一个实际问题。我们的应用程序启动时间的很大一部分是在EDT上加载类和字体/图像。其中大部分可以归因于Swing和相关的库。

    以下是som的背景:和许多其他Swing应用一样,在启动时我们正在预先构建许多表单,以便使UI更具响应性。在分析之后,我们发现表单构造的实际时间相对比较快——慢的是加载所有类和字体(磁盘读取是必需的) 在公司设置中,安装了on-access病毒扫描程序、监视扫描程序、审计跟踪器,天知道硬盘驱动器上还有什么)。

    我们试图在后台线程中构造相同的表单(违反Swing的规则),然后将它们丢弃。完成后,我们在EDT上构造相同的表单,这比加载所有类和磁盘缓存中的任何其他文件快得多。它对我们有用,除非真的发生不好的事情,否则我们可能会继续这样做。

    我想问的是,这是一个安全的做法,一个良好的做法还是黑客?

    3 回复  |  直到 14 年前
        1
  •  2
  •   mdma    14 年前

    证据似乎表明它是安全的——但是,正如ddimitrov在评论中所说的那样——由于未发布的更改,不可能发现细微的线程错误,因为典型的机器只有几个内核,并且L2/L3缓存是共享的(一级缓存是每个核心的,但通常非常小。)

    或者,可以在单独的线程上运行辅助事件队列(例如模式对话框和 spin

        2
  •  2
  •   Konrad Garus    14 年前

    http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html (单线程规则)

    如果您害怕或想要一些反馈/调试,请查看这个FEST/Swing工具: http://fest.easytesting.org/swing/wiki/pmwiki.php?n=FEST-Swing.EDT RepaintManager 如果违反EDT访问策略,则会失败。

    您可能会发现这也很有帮助: http://weblogs.java.net/blog/alexfromsun/archive/2006/02/debugging_swing.html

    他们没有明确提到类加载,但他们确实解释了EDT访问策略是关于什么的。

        3
  •  0
  •   Bill K    14 年前

    这些曾经是sun的指导方针,但sun将它们改为您指定的——所以我肯定有人发现或制造了潜在的冲突,但我也肯定这将是他妈的难以打击,因为应用程序仍然工作,几乎没有遵循这些指导方针。

    EDT仅用于避免线程冲突,因为Swing是单线程的(按设计)。如果您只是加载类而没有实例化任何类,那么您就不会为任何线程问题敞开心扉。