Java多線程學(xué)習(xí)筆記1

多線程學(xué)習(xí)筆記

在之前的java開(kāi)發(fā)中一般都是java web方向的工作,對(duì)多線程使用的非常少。了解僅限于RunnableThread的區(qū)別與使用。最近在做小工具的時(shí)候用到了多線程,從零開(kāi)始學(xué)習(xí)關(guān)于多線程和并發(fā)方面的知識(shí)。

并發(fā)和多線程之間的關(guān)系

并發(fā)與多線程之間的關(guān)系就是目的與手段之間的關(guān)系。并發(fā)(Concurrent)的反面是串行。并發(fā)的極致就是并行(Parallel)。多線程就是將原本可能是串行的計(jì)算“改為”并發(fā)(并行)的一種手段、途徑或者模型。因此,有時(shí)我們也稱多線程編程為并發(fā)編程。當(dāng)然,目的與手段之間常常是一對(duì)多的關(guān)系。并發(fā)編程還有其他的實(shí)現(xiàn)途徑,多線程編程往往是其他并發(fā)編程模型的基礎(chǔ)。

實(shí)現(xiàn)多線程的方式:1.繼承Thread類,2.實(shí)現(xiàn)Runnable接口。實(shí)際上Thread也是Runnable的一個(gè)子類。使用繼承Thread最大的局限性在于不支持多繼承。所以為了支持多繼承,就會(huì)使用Runnable接口的方式。
Runnable接口就是定義了一個(gè)run方法。所以重點(diǎn)看Thread類。
Thread有9個(gè)構(gòu)造方法。常用的有Thread()Thread(Runnable)兩個(gè),構(gòu)造方法都調(diào)用了init()方法,初始化一個(gè)線程。

   private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc) {
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }
        this.name = name.toCharArray();
        Thread parent = currentThread();
        SecurityManager security = System.getSecurityManager();
        if (g == null) {
            /* 判斷是否為 applet */
            /* 如果有security manager */
            if (security != null) {
                g = security.getThreadGroup();
            }
            /* 如果 security manager getThreadGroup 為null*/
            if (g == null) {
                g = parent.getThreadGroup();
            }
        }
        /* 不管是否是傳入?yún)?shù)的ThreadGroup 都再進(jìn)行security manager 檢查*/
        g.checkAccess();

        /*
         * 權(quán)限控制?
         */
        if (security != null) {
            if (isCCLOverridden(getClass())) {
                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
            }
        }
        // 添加在未啟動(dòng)的線程組
        g.addUnstarted();

        this.group = g;
        //是否是守護(hù)線程
        this.daemon = parent.isDaemon();
        this.priority = parent.getPriority();
        if (security == null || isCCLOverridden(parent.getClass()))
            this.contextClassLoader = parent.getContextClassLoader();
        else
            this.contextClassLoader = parent.contextClassLoader;
        this.inheritedAccessControlContext =
                acc != null ? acc : AccessController.getContext();
        this.target = target;
        setPriority(priority);
        if (parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals =
                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        /* Stash the specified stack size in case the VM cares */
        this.stackSize = stackSize;

        /* Set thread ID */
        tid = nextThreadID();
    }

通過(guò)init(ThreadGroup, Runnable, String, stackSize, AccessControlContext)方法來(lái)完成Thread對(duì)象的創(chuàng)建 整個(gè)過(guò)程是

  1. registerNatives() 靜態(tài)塊, 判斷name。設(shè)置name,獲取Thread parent ,獲取SecurityManager 。
  2. 檢查security .線程組中的nUnstartedThreads++ 。
  3. 設(shè)置ThreadGroup線程組,設(shè)置daemon是否守護(hù)線程,priority優(yōu)先,ContextClassLoaderclassLoader,inheritedAccessControlContext 繼承的訪問(wèn)控制上下文,target為繼承Runnable接口的對(duì)象。inheritableThreadLocals threadLocal,stackSize,id 設(shè)置。
    整個(gè)Thread 對(duì)象的創(chuàng)建過(guò)程大概就是這樣一個(gè)流程。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容