1. 程式人生 > >ThreadLocal類維持執行緒封閉性

ThreadLocal類維持執行緒封閉性

在《多執行緒採用鎖併發控制》一文中採用鎖保證了多執行緒下類的成員變數的同步。如果需要保證執行緒內部對變數的訪問是隔離的,執行緒內部對變數的操作不會影響其他的執行緒,這又該如何操作了。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特別適用於長流程中的上下文的實現,在長流程中可以將變數的值放入上下文中進行共享,後面的流程可以共享前面的資料。