ThreadLocal是什么
ThreadLocal為解決多線程程序的并發(fā)問題提供一種新的思路。
使用這個工具類可以很簡潔地編寫出有優(yōu)美的多線程程序
ThreadLocal 有什么用
- 保護共享資源不受污染。
- 當使用ThreadLocal維護變量時,ThreadLocal為每個使用該變量的線程提供獨立的變量副本,所以每一個線程都一個獨立改變自己的副本,而不會影響其它線程所對應的副本。
- 從線程的角度看,目標變量就像是線程的本地變量,這也是類名中“Local”所要表達的意思。
- 數據庫連接池
ThreadLocal如何用
- void set(Object value)設置當前線程的線程局部變量的值。
- public Object get()該方法返回當前線程所對應的線程局部變量。
- public void remove()將當前線程局部變量的值刪除,目的是為了減少內存的占用,該方法是JDK 5.0新增的方法。
- protected Object initialValue()返回該線程局部變量的初始值,該方法是一個protected的方法,顯然是為了讓子類覆蓋而設計的。這個方法是一個延遲調用方法,在線程第1次調用get()或set(Object)時才執(zhí)行,并且僅執(zhí)行1次。ThreadLocal中的缺省實現直接返回一個null。
代碼示例
//不使用 ThreadLocal
class TestNum{
private int num =0;
public int getNextNum() {
return num++;
}
}
class TestCLient extends Thread {
private TestNum testNum;
public TestCLient(TestNum testNum) {
this.testNum = testNum;
}
@Override
public void run() {
super.run();
for(int i=0;i<3;i++) {
System.out.println("thread[" + Thread.currentThread().getName()
+ "] -------> i=" + testNum.getNextNum());
}
}
}
TestNum testNum = new TestNum();
TestCLient t1 = new TestCLient(testNum);
TestCLient t2 = new TestCLient(testNum);
TestCLient t3 = new TestCLient(testNum);
t1.start();
t2.start();
t3.start();
輸出結果:
thread[Thread-1] -------> i=1
thread[Thread-0] -------> i=1
thread[Thread-0] -------> i=3
thread[Thread-2] -------> i=0
thread[Thread-2] -------> i=5
thread[Thread-2] -------> i=6
thread[Thread-0] -------> i=4
thread[Thread-1] -------> i=2
thread[Thread-1] -------> i=7
每個線程的i都會被污染
//使用 ThreadLocal
class TestNum2{
private ThreadLocal<Integer> tl = new ThreadLocal<Integer>();
public int getNextNum() {
Integer a = tl.get();
if(a == null) {
System.out.println("a == "+ Thread.currentThread().getName());
a =0;
tl.set(a);
}
tl.set(++a);
return tl.get();
}
}
輸出結果:
a == Thread-0
thread[Thread-0] -------> i=1
thread[Thread-0] -------> i=2
thread[Thread-0] -------> i=3
a == Thread-2
thread[Thread-2] -------> i=1
thread[Thread-2] -------> i=2
thread[Thread-2] -------> i=3
a == Thread-1
thread[Thread-1] -------> i=1
thread[Thread-1] -------> i=2
thread[Thread-1] -------> i=3
每個線程的i都會是局部變量其他線程不會污染
2016.10.31