Thread原理剖析

記得剛開始面試的時候被面試官問過Thread如果直接調用run方法嗎?如果調用run方法會創建新的線程嗎?
初級回調只回答到面試官問的問題。
Thread肯定是可以調用run方法的,對象調方法。
直接調用run方法不會創建線程的,必須調用start方法纔回創建線程。
當Thread 調用start方法的時候,裏面會調用一個nativeCreate的方法,這個方法最終會調用c++代碼的pthread_create方法,這個方法會創建一個線程,線程成功之後會調線程的run方法,這也是爲什麼調完start方法之後會自動調用run方法的原因。

中級回答進一步擴展(yield、wait、notify、notifyAll)。
yield :放棄當前的執行權,程序進入阻塞競爭狀態。
wait :當前線程等待狀態,放棄鎖,所以必須在同步代碼中調用。
notify:喚醒當前線程的wait狀態,執行wait後面的代碼。
notifyAll:喚醒所有線程的wait狀態,線程處於競爭狀態。

高級回答ThreadLocalMap相關。
Thread 裏面維護了一個ThreadLocal.ThreadLocalMap 存儲鍵值對的對象,它的鍵就是ThreadLocal自身,值則是ThreadLocal對象設置的值了。

 public static void main(String[] arg0) throws Exception {
        //不同線程同一個threadLocal的情況
        Thread thread1 = new Thread() {
            @Override
            public void run() {
                //會判斷與thread1對應的ThreadLocalMap是否初始化過,如果沒有初始化則直接初始化並且將threadLocal作爲key 1作爲value存入ThreadLocalMap中
                threadLocal.set(1);
                //get的時候 找到當前線程鎖對應的ThreadLocalMap對象,然後調用ThreadLocalMap.get(threadLocal)取出對應的值。
                System.out.println("thread1 =" + threadLocal.get());
            }
        };
        thread1.start();

        Thread thread2 = new Thread() {
            @Override
            public void run() {
                //get的時候 從當前線程裏面取出ThreadLocalMap對象,當前ThreadLocalMap並沒有初始化,此時會去初始化,然後調用ThreadLocalMap.get(threadLocal),此時獲取的就是null了
                System.out.println("thread1 =" + threadLocal.get());
            }
        };
        thread2.start();
        
        //ThreadLocalMap把key和value封裝成Entry對象 繼承裏WeakReference,是一個弱引用,使用開放地址方來解決衝突,裏面的hashcode用的是神奇數據,並不是自生的hashcode
        final ThreadLocal<Integer> threadLocal1 = new ThreadLocal<>();
        final ThreadLocal<Integer> threadLocal2 = new ThreadLocal<>();
        final ThreadLocal<Integer> threadLocal3 = new ThreadLocal<>();
        Thread thread3 = new Thread() {
            @Override
            public void run() {
                threadLocal1.set(1);
                threadLocal2.set(2);
                threadLocal3.set(3);
                System.out.println("threadLocal1 =" + threadLocal1.get());
                System.out.println("threadLocal2 =" + threadLocal2.get());
                System.out.println("threadLocal3 =" + threadLocal3.get());
            }
        };
        thread3.start();
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章