大家應該都看過西遊記吧。
西遊記講的是唐僧師徒西天取經,經歷九九八十難,終於完成取經任務,修成正果的故事。
取經時經過了很多的國家。這個過程用java代碼體現會是什麼樣呢。
畫外音:為了截圖不至於太長,注釋使用不太規範
有一個唐僧類。
唐僧類包含了一個取經的方法。取經的方法調用了另外的拜訪各國的方法。最後調用了一個取經完成的方法。
那大家有沒有記得,唐僧沒到一個國家都要找國王在通關文牒上蓋章。這個通過文牒肯定在最後取經完成時也是要展示給唐王驗證的。
那這個通關文牒怎麼體現在上面的代碼中呢。
把通關文牒作為一個方法參數,在所有的方法裡都傳遞一遍?
大家有注意到我代碼裡拜訪各國的方法間的一堆省略號,確定要給這麼多方法都加一個參數,然後每次調用都去傳遞?
其實這些方法的調用都是在一個線程中完成的。對ThreadLocal有一定了解同學,這裡可以使用ThreadLocal了。
下面來看下,用上ThreadLocal後的唐僧取經的代碼。
上面是使用了ThreadLocal的唐僧取經,拜訪各國和取經完成的方法都不需要傳遞參數。只需要在方法中對應的完成對通關文牒的修改以及取經完成時輸出通關文牒即可。
這就是ThreadLocal的一個特點,貫穿整個線程,在線程內傳遞。
細心的朋友可能發現了這個ThreadLocal變量是static的。
那如果有別的唐僧也對這個通關文牒做修改了,那兩個唐僧的通關文牒的內容不就混亂了嗎。
嗯?不是只有一個唐僧嗎。
我們這裡設定的是一個多維空間,存在平行空間的(多線程)。可以同時有多個唐僧進行取經的。
那多個平行空間(多線程)的多個唐僧同時取經,他們的通關文牒會不會搞混亂呢。
可以肯定的告訴大家,不會混亂的。這就是ThreadLocal的另一個特點,變量是線程間隔絕的,每個線程(平行空間)使用的都是自己的一套。
那ThreadLocal是怎麼做到這一點的呢。
讓我們進入ThreadLocal的代碼中看個究竟。
我們從ThreadLocal的get方法進去。
先獲取到當前線程,然後用當前線程獲取到一個ThreadLocalMap(key-value形式),通過當前ThreadLocal對象作為key獲取到的value就是我們存放在ThreadLocal中的通關文牒的內容了。
我們再看看上面代碼中的getMap方法做了什麼。
從getMap方法裡看到方法內部的邏輯是返回了當前線程的一個ThreadLocalMap類型的屬性。從這裡就保證了我們取到的變量是只屬於當前線程的了。
那為什麼從線程取到的這個ThreadLocalMap是一個key-value形式的呢。
想想,唐僧西天取經,不只是通關文牒這個東西一直在用吧(線程中多方法間傳遞使用)。比如紫金缽盂。這樣的話就需要多個ThreadLocal類型的變量了。
這樣就能理解了吧,這個ThreadLocalMap的key就是不同的ThreadLocal變量,而ThreadLocalMap存放的value就是不同的ThreadLocal變量中存放的值了。
今天辛苦唐僧同學了。
有自學java的同學,可以看看這本書