在引入Java内存模型之后,Swing准则已更改为声明任何Swing组件都需要在EDT上实例化,以避免未发布的实例状态。是否允许在非EDT线程中加载Swing类?
我无法在任何地方找到的是类加载是否也要求在EDT上,或者我们能否在后台线程中预加载关键的Swing类? Sun/Oracle对此有任何官方声明吗?是否有已知的类可以保持非线程安全的静态状态,因此需要在EDT上加载?
澄清解决Nemi的问题:这是一个实际问题。我们的应用程序启动时间的相当一部分,是在EDT上花费类加载和字体/图像加载。其中大部分可归因于Swing和相关的图书馆。
以下是som背景:与其他许多Swing应用程序一样,我们在启动时预构造了许多表单,以便使UI更加灵敏。分析后,我们发现表单构建的实际时间相对较快 - 缓慢的是所有类和字体的加载(磁盘读取为缓慢在公司设置与按访问病毒扫描仪,监视扫描仪,审计跟踪器和天知道还有什么别的硬盘驱动器)。
我们试图在后台线程中构造相同的表单(违反了Swing的规则),然后将它们丢弃。一旦我们完成了,我们在EDT上构建相同的表单,因为所有类都被加载并且其他任何文件都在磁盘缓存中,所以速度更快。它适用于我们,我们可能会继续这样做,除非发生非常糟糕的事情。
我在问的是这是安全的做法,一个好的做法还是一个黑客?
特别是,两个单班我能想到的是UIManager的和AppContext的。两个javadocs都没有说明它们是否应该是线程安全的。 除了isDisposed()方法没有正确读取状态(需要同步)之外,AppContext的外观正确同步。 UIManager对所有人都是免费的,但一旦EDT开始,我不认为其他线程会改变它。 – ddimitrov 2010-06-07 01:34:05
这是一个有趣的问题。这是纯粹的学术,还是有一个真正的问题,你正在试图解决?我想不出有什么好的理由可以做到这一点。 – Nemi 2010-06-07 16:28:52
@Nemi,给问题增加了更多的上下文 – ddimitrov 2010-06-07 23:09:53