天天看點

JVM---雙親委派模型(源碼詳解)

含義

1.雙親委派模型是從JDK1.2開始至今都在沿用的類加載模型,具體的邏輯是:

先看源碼:

protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }
           

注釋已經很清晰了:

首先,根據類的全限定名通過findLoadedClass方法查詢該類是否已被加載,如果已經被加載過了則判斷resolve的值,該值是辨別類是否link了,(This (misleadingly named) method may be

used by a class loader to link a class.)預設傳false,也就是說直接傳回了該類.重點是如果該類沒有加載過:再判斷是否有父類加載器(通過組合的方式持有),如果有父類加載器,就用父類加載器加載,如果沒有說明其上層隻剩啟動類加載器了,就用啟動類加載器加載,(因為啟動類加載器是通過c++寫的).

如果其父類加載器或者啟動類加載器都不能加載,會抛出異常,然後由本類加載器的findClass方法進行加載,然後記錄類加載器的的狀态資訊

優點

優點也就是使用該模型的必要性:這種加載機制可以使類連同其加載器有了一種具有優先級的層次關系,保證了同一個類的全限定名隻對應一個類,保證了其唯一性,否者,根本就沒法保證java的工作機制.

缺點

顯而易見,如果上層的類加載器在工作的時候需要下層的類加載器進行加載操作則是不支援的,但這種場景有很多的場景,比如,JNDI,JDBC,JBI等涉及到SPI(接口提供者)

的地方,都是為了解決這個問題而提出的方式,具體可以看下篇 破壞雙親委派模型.這裡不做細緻的記錄.

繼續閱讀