關於類加載的並發控制鎖(ClassLoadingLock)


死鎖

在JDK1.7以前,java.lang.ClassLoader的一些核心方法是被synchronized修飾的,比如loadClass,以下摘自JDK6下java.lang.ClassLoader的部分方法:

protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {...}
 
private synchronized Class loadClassInternal(String name) throws ClassNotFoundException {...}
 
private synchronized void checkCerts(String name, CodeSource cs) {...}
 
private static synchronized void initSystemClassLoader() {...}

由於方法被synchronized修飾,當BundleA加載PackageB時,要先鎖定BundleA類加載器的實例對象,然后將請求委派給BundleB的類加載器處理,但如果這時BundleB也正好想要加載packageA的類,就需要先鎖定BundleB類加載器再去請求BundleA的加載器處理,這樣兩個加載器都在等待對方處理自己的請求,但有各自又都持有己方的鎖,就造成了死鎖狀態。

 

 


BundleA和BundleB相互依賴
 解決
在JDK1.7之后對這個問題做出了優化,可以以手動注冊的方式將類加載標識為具備並行能力,之后在加載類的時候棄用了方法級別synchronized的方式,改為了為每個要加載的class文件(全路徑名)都對應一個Object對象鎖。加鎖的時候如果加載器具備並行能力,那么就不再對類加載器進行加鎖,而是找到加載類文件對應的Object鎖進行加鎖操作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM