每個執行緒都有一個ThreadLocalMap物件,ThreadLocalMap是Thread的一個內部類,可以把ThreadLocalMap理解成一個Map,這個Map裡存放這一個Thread的所有執行緒變數。
在我們建立一個執行緒變數 maxLife 之後,執行其set方法,其實是以maxLife這個物件為鍵,以0為值,然後將這組鍵值對放入當前執行緒的ThreadLocalMap物件中。
如果你不明白這意味著什麼,接著往下看。
為了說明ThreadLocal有什麼不同,我們直接上程式碼。
首先,我們在類中定義一個全域性變數,後邊的所有執行緒都共享這個變數。
ThreadLocal<Integer> maxLife = null;
然後建立一個執行緒A,並在這個執行緒中為maxLife賦一個新物件,並且為其設定值
maxLife = new ThreadLocal<Integer>()
maxLife.set(0);
這個時候讓A執行緒別再往下跑了,同時我們建立一個B執行緒,然後在B執行緒裡
maxLife = new ThreadLocal<Integer>();
執行完這一段,把B暫停了,然後再回到A執行緒,執行
Integer i = maxLife.get();
這個時候你如果列印i,那麼你會看到一個null。
這是為什麼呢?
因為maxLife的get方法,其實是以maxLife這個物件本身為鍵,然後去當前執行緒的ThreadLocalMap中獲取其所對應的值,A執行緒中我們new了一個物件然後當成key,B執行緒中我們又new了一個,我們知道A和B先後new 的兩個物件不是同一個物件,那麼以不同的物件作為key去一個map裡面取值會怎樣呢?
也就是說 maxLife 這個變數,在A和B中是共享的,但是maxLife作為key在A和B各自的ThreadLocalMap中對應的值是不一樣的,所以我們定義ThreadLocal變數,最好在一開始的時候就為其new一個值,而不是讓它等於null。
完畢。