ThreadLocal類維持執行緒封閉性
阿新 • • 發佈:2019-01-06
在《多執行緒採用鎖併發控制》一文中採用鎖保證了多執行緒下類的成員變數的同步。如果需要保證執行緒內部對變數的訪問是隔離的,執行緒內部對變數的操作不會影響其他的執行緒,這又該如何操作了。ThreadLocal物件通常用於防止對可變的單例項變數或全域性變數進行共享。
public class MyCounter implements Runnable { private static ThreadLocal<Long> count = new ThreadLocal<Long>(){ public Long initialValue() { return 0L; } }; public Long getNext() { count.set(count.get()+1); return count.get(); } public synchronized void run() { System.out.println("thread id:"+Thread.currentThread().getId()+",count:"+getNext()); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(3); MyCounter countThread = new MyCounter(); for(int i=0; i<9; i++){ executorService.submit(countThread); } } }
上面的程式通過ThreadLocal實現了計數器的初始化,線上程的run方法中打印出當前的執行執行緒和計數器的下一個值。看看程式執行的某一次結果。
thread id:10,count:1
thread id:12,count:1
thread id:11,count:1
thread id:12,count:2
thread id:10,count:2
thread id:12,count:3
thread id:11,count:2
thread id:12,count:4
thread id:10,count:3
從結果中可以看出執行緒10,11,12獲取的計數值都是獨立遞增的。這實現了我們的期望,執行緒之前的操作是隔離的,每個執行緒獲取獨立的值。ThreadLocal特別適用於長流程中的上下文的實現,在長流程中可以將變數的值放入上下文中進行共享,後面的流程可以共享前面的資料。