Java虛擬機(jī)類加載器之雙親委派機(jī)制模型案例
1. 雙親委派模型是什么?
當(dāng)某個(gè)類加載器需要加載某個(gè).class字節(jié)碼文件時(shí),它首先把這個(gè)任務(wù)委托給它的上級(jí)類加載器,遞歸這個(gè)操作,如果上級(jí)的類加載器沒有加載,自己才會(huì)去加載這個(gè)類。
2. 雙親委派模型的工作原理?
1.如果一個(gè)類加載器收到了類加載的請(qǐng)求,它首先不會(huì)自己去嘗試加載這個(gè)類,而是把這個(gè)請(qǐng)求委派給父類加載器去執(zhí)行;
2.如果父類加載器還存在其父類加載器,則進(jìn)一步向上委托,依次遞歸,請(qǐng)求最終將到達(dá)頂層的啟動(dòng)類加載器;(每一個(gè)層次的類加載器都是如此,因此所有的加載請(qǐng)求最終都應(yīng)該傳送到最頂層的啟動(dòng)類加載器中。)
3.如果父類加載器可以完成類加載任務(wù),就成功返回;倘若父類加載器反饋?zhàn)约簾o法完成這個(gè)加載請(qǐng)求(它的搜索范圍中沒有找到所需的類)時(shí),子加載器才會(huì)嘗試自己去完成加載。
以上便是雙親委派模型的工作原理。
雙親委派模型對(duì)于保證Java程序的穩(wěn)定運(yùn)作極為重要,但它的實(shí)現(xiàn)卻異常簡(jiǎn)單,用以實(shí)現(xiàn)雙親委
派的代碼只有短短十余行,全部集中在java.lang.ClassLoader的loadClass()方法之中。
雙親委派模型的核心代碼:
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// 首先,檢查這類是否已經(jīng)被加載過了
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
if (parent != null) {
//如果存在父類加載器,則取找該類的父類加載器
c = parent.loadClass(name, false);
} else {
//返回由引導(dǎo)類加載器加載的類;如果未找到,則返回 null。
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// 如果父類加載器拋出ClassNotFoundException異常
// 則說明父類加載器無法完成加載請(qǐng)求
}
if (c == null) {
// 在父類加載器無法加載時(shí)
// 再調(diào)用本身的findClass方法來進(jìn)行加載
long t1 = System.nanoTime();
c = findClass(name);
// 這是定義類加載器;記錄統(tǒng)計(jì)數(shù)據(jù)
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
這段源碼邏輯:
1.首先,檢查請(qǐng)求加載的類型是否已經(jīng)被加載,倘若沒有則調(diào)用父類加載器loadClass()方法;
2.如果父類加載器為空,則默認(rèn)使用啟動(dòng)類加載器作為父加載器。
3.如果父類加載器加載失敗,拋出ClassNotFoundException異常,這時(shí)候才調(diào)用自己的findClass()方法嘗試進(jìn)行加載。
可參考網(wǎng)上的雙親委派模型流程圖:

3. 雙親委派機(jī)制的優(yōu)勢(shì)?
1.保證基礎(chǔ)類僅加載一次,不會(huì)讓JVM中存在重名的類。
防止重復(fù)加載同一個(gè).class文件,比如String.class,每次加載都委托給父加載器,最終都是BootstrapClassLoader,都保證java核心類都是BootstrapClassLoader加載的,加載過了,就不用再加載一遍,保證了java的安全與穩(wěn)定性。
2.保護(hù)程序安全,防止核心.class文件被隨意篡改。
通過委托方式,不會(huì)去篡改核心.class,即使篡改也不會(huì)去加載,即使加載也不會(huì)是同一個(gè).class對(duì)象了。不同的加載器加載同一個(gè).class也不是同一個(gè)Class對(duì)象。這樣保證了Class執(zhí)行安全。
到此這篇關(guān)于Java虛擬機(jī)類加載器之雙親委派機(jī)制模型案例的文章就介紹到這了,更多相關(guān)Java虛擬機(jī)類加載器之雙親委派內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Spring AOP 攔截器的基本實(shí)現(xiàn)
本篇文章主要介紹了詳解Spring AOP 攔截器的基本實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03
SpringCloud Zuul服務(wù)功能與使用方法解析
這篇文章主要介紹了SpringCloud Zuul服務(wù)功能與使用方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
java基于C/S模式實(shí)現(xiàn)聊天程序(客戶端)
這篇文章主要為大家詳細(xì)介紹了java基于C/S模式實(shí)現(xiàn)聊天程序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01
java gui詳解貪吃蛇小游戲?qū)崿F(xiàn)流程
剛開始學(xué)JAVA GUI,就練手寫了一個(gè)小時(shí)候經(jīng)常在諾基亞上玩的一個(gè)小游戲__貪吃蛇.做的比較簡(jiǎn)單,但還是可以玩的.感興趣的朋友快來看看吧2021-11-11
詳解用maven搭建springboot環(huán)境的方法
本篇文章主要介紹了詳解用maven搭建springboot環(huán)境的方法,這里整理了詳細(xì)的代碼,非常具有實(shí)用價(jià)值,有需要的小伙伴可以參考下2017-08-08

