在引入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