線程的生命週期一共有5種狀態:new、runnable、running、blocked、dead.java
實例化一個Thread類的對象,此線程即進入new狀態,分配有本身的內存空間,但該線程並無運行,此時線程not alive。數據庫
線程已經被啓動,在等待被分配給CPU時間片。也就經過調用線程實例的start()方法來啓動線程,進入runnbale。runnable狀態的線程已經具有了運行條件,但尚未被分到CPU,不必定會被當即執行,線程處於就緒隊列中。此時線程alive。安全
線程得到CPU資源正在執行任務(run()方法),除非此線程自動放棄CPU資源或者有優先級更高的線程進入,線程將一直運行到結束。線程alive。ide
因爲某種緣由致使正在運行的線程讓出CPU並暫停本身的執行,即進入阻塞狀態。this
此時線程alive。spa
線程執行完畢或被其餘線程殺死。此時線程不可能再進入就緒狀態等待執行。線程
處於Dead狀態的線程not alive。code
運行在後臺的線程。如Java的垃圾回收,數據庫鏈接池等都是守護線程。對象
守護線程與普通線程在寫法上沒有太大區別,調用線程對象的方法setDaemon(true)就能夠將其設置爲守護線程。生命週期
public final void setDaemon(boolean on) //該方法碧璽在啓動線程前調用
當正在運行的線程都是守護線程時,Java虛擬機退出。即,Java虛擬的運行只關係非守護線程,當非守護線程都運行完畢時,不管守護線程是否退出,Java虛擬機都會中止。
ThreadLocal爲每一個使用該變量的線程提供獨立的變量副本,每個線程均可以獨立地改變本身的副本,而不會影響其餘線程所對應的副本。
ThreadLocal的set()方法源碼:
/** * Sets the current thread's copy of this thread-local variable * to the specified value. Most subclasses will have no need to * override this method, relying solely on the {@link #initialValue} * method to set the values of thread-locals. * * @param value the value to be stored in the current thread's copy of * this thread-local. */
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
複製代碼
分析它的實現:首先經過getMap(Thread t)方法獲取一個和當前線程相關的ThreadLocalMap,而後將變量的值設置到這個ThreadLocalMap對象中,若map == null
,則新建一個ThreadLocalMap而後再賦值。
ThreadLocalMap是ThreadLocal類的一個靜態內部類,實現了鍵值對的設置和獲取。每一個線程中都有一個獨立的ThreadLocalMap副本,它所存儲的值,只能被當前線程讀取和修改。 ThreadLocal類經過操做每個線程特有的ThreadLocalMap副本,從而實現了變量訪問在不一樣線程中的隔離。 ThreadLocalMap存儲的鍵值對中的鍵是this對象指向的ThreadLocal對象。