ThreadLocal的作用
ThredLocal是多線程中爲了保證線程安全而提供的工具類,它可以代表一個線程局部變量,該類支持泛型。
- 每個線程中都有一個自己的ThreadLocalMap類對象,可以將線程自己的對象保持到其中,各管各的,線程可以正確的訪問到自己的對象。
- 將一個共用的ThreadLocal靜態實例作爲key,將不同對象的引用保存到不同線程的ThreadLocalMap中,然後在線程執行的各處通過這個靜態ThreadLocal實例的get()方法取得自己線程保存的那個對象,避免了將這個對象作爲參數傳遞的麻煩。
ThreadLocal的使用場景
如果訪問的資源無限且需要同步,使用該資源不會影響別的線程,每個線程對應一個實例)的對象的訪問,那就可以使用ThreadLocal來作爲線程局部變量。
ThreadLocal與volatile的區別
volatile和ThreadLocal看起來都是用於變量,但volatile修飾的變量始終只有一份,volatile的作用和同步機制一樣,如果只是對一兩個實例變量進行線程同步就沒必要使用synchronized,使用volatile更方便。但是ThreadLocal是在每一個線程中都存放了一份資源,每個線程各玩各的,互不影響。
ThreadLocal的使用方法
- set():爲ThreadLocal實例設置值
- get():獲取ThreadLocal實例對應的值
- remove():移除ThreadLocal實例對應的值
- 以上方法是最基本的,如果泛型是String,還可以使用String的方法。
ThreadLocal實例
public class ThreadLocalDemo {
//創建ThreadLocal實例
ThreadLocal<String> thr = new ThreadLocal();
//初始化Threadlocal實例的數據
public ThreadLocalDemo(String thr) {
this.thr.set(thr);
}
public static void main(String[] args) {
ThreadLocalDemo t = new ThreadLocalDemo("FUCK");
Test tes = new Test(t);
Test tes2 = new Test(t);
new Thread(tes,"A線程-").start();
new Thread(tes,"B線程-").start();
}
}
//測試ThreadLocal線程
class Test implements Runnable{
private ThreadLocalDemo tld;
public Test(ThreadLocalDemo tld) {
this.tld = tld;
}
@Override
public void run() {
for(int i=0; i < 6; i++) {
tld.thr.set(i + "");
//i==5將ThreadLocal實例的值設置爲線程名
if(i == 3)
tld.thr.set(Thread.currentThread().getName());
try {
Thread.sleep(1);//當前線程讓出執行權
} catch (InterruptedException e) {e.printStackTrace();}
System.out.println(Thread.currentThread().getName() + tld.thr.get());
}
}
}
- 實例解析:在測試ThreadLocal的線程中,當i==3時,將ThreadLocal實例的值設置爲當前線程名,所以會看到A線程與B線程的ThreadLocal是不同的,互不影響。