1. 程式人生 > 實用技巧 >再挖一挖ThreadLocal

再挖一挖ThreadLocal

關於ThreadLocal原始碼分析的文章可以說多如牛毛,不僅是由於ThreadLocal原始碼簡潔,還因為它是由Java界的兩個大師級的作者編寫,Josh Bloch和Doug Lea。Josh Bloch 在 Sun 公司多年為 Java 平臺作出了傑出貢獻,包括JDK5語言增強、Java集合(Collections)框架,現在 Google 就職,是獲獎圖書《Effective Java》及《Effective Java: Second Edition》的作者。Doug Lea是JUC包的作者,Java併發程式設計的泰斗。筆者寫這篇部落格起初是因為一直對ThreadLocal中的魔數0x61c88647有疑惑,為使這塊內容較完整,也就按照通常的內容結構來寫了,然而在寫的過程中再次感受到,即使再熟悉的東西,仔細思考總結,依然收穫滿滿,推薦小夥伴們也動筆寫起來~

目錄

一. ThreadLocal做什麼的

​ ThreadLocal類可以看作為執行緒提供區域性變數的工具類,也就是說如果定義了一個ThreadLocal,每個執行緒往這個ThreadLocal中讀寫是執行緒隔離的,互相之間不會影響,是執行緒安全的。與區域性變數對應的就是共享變量了,如果多個執行緒共享一個變數,併發環境下讀寫共享變數是執行緒不安全的,為處理這種併發問題,常用做法就是加鎖。加鎖還是使用區域性變數就需要我們根據實際情況去權衡了。

​ 我們先看下ThreadLocal的用法,以下是原始碼中提供的例子:為每個執行緒生成唯一id,執行緒第一次訪問ThreadLocal會觸發initialValue()方法,因此執行緒呼叫ThreadId.get()時得到唯一id:

import java.util.concurrent.atomic.AtomicInteger;

 public class ThreadId {
     // Atomic integer containing the next thread ID to be assigned
     private static final AtomicInteger nextId = new AtomicInteger(0);

     // Thread local variable containing each thread's ID
     private static final ThreadLocal<Integer> threadId = new ThreadLocal<Integer>() {
             	@Override 
     					protected Integer initialValue() {
              	return nextId.getAndIncrement();
         }
     };

     // Returns the current thread's unique ID, assigning it if necessary
     public static int get() {
         return threadId.get();
     }
 }