Java多執行緒程式設計-(3)-執行緒本地ThreadLocal的介紹與使用
阿新 • • 發佈:2018-12-31
原文出自 : https://blog.csdn.net/xlgen157387/article/details/78114278
ThreadLocal簡介
我們通過上兩篇的學習,我們已經知道了變數值的共享可以使用public static
變數的形式,所有的執行緒都使用同一個被public static
修飾的變數。
那麼如果我們想實現每一個執行緒都有自己的共享變數該如何解決哪?JDK提供的ThreadLocal正是為了解決這樣的問題的。
類ThreadLocal主要解決的就是每個執行緒繫結自己的值,可以將ThreadLocal類比喻成全域性存放資料的盒子,盒子中可以儲存每個執行緒的私有變數。
先舉個栗子
public class ThreadLocalDemo {
public static ThreadLocal<List<String>> threadLocal = new ThreadLocal<>();
public void setThreadLocal(List<String> values) {
threadLocal.set(values);
}
public void getThreadLocal() {
System.out.println(Thread.currentThread().getName());
threadLocal.get ().forEach(name -> System.out.println(name));
}
public static void main(String[] args) throws InterruptedException {
final ThreadLocalDemo threadLocal = new ThreadLocalDemo();
new Thread(() -> {
List<String> params = new ArrayList<>(3);
params .add("張三");
params.add("李四");
params.add("王五");
threadLocal.setThreadLocal(params);
threadLocal.getThreadLocal();
}).start();
new Thread(() -> {
try {
Thread.sleep(1000);
List<String> params = new ArrayList<>(2);
params.add("Chinese");
params.add("English");
threadLocal.setThreadLocal(params);
threadLocal.getThreadLocal();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
執行結果:
Thread-0
張三
李四
王五
Thread-1
Chinese
English
- 1
- 2
- 3
- 4
- 5
- 6
- 7
可以,看出雖然多個執行緒對同一個變數進行訪問,但是由於threadLocal
變數由ThreadLocal
修飾,則不同的執行緒訪問的就是該執行緒設定的值,這裡也就體現出來ThreadLocal的作用。
當使用ThreadLocal維護變數時,ThreadLocal為每個使用該變數的執行緒提供獨立的變數副本,所以每一個執行緒都可以獨立地改變自己的副本,而不會影響其它執行緒所對應的副本。
ThreadLocal與synchronized同步機制的比較
在同步機制中,通過物件的鎖機制保證同一時間只有一個執行緒訪問變數。這時該變數是多個執行緒共享的,使用同步機制要求程式慎密地分析什麼時候對變數進行讀寫,什麼時候需要鎖定某個物件,什麼時候釋放物件鎖等繁雜的問題,程式設計和編寫難度相對較大。
ThreadLocal是執行緒區域性變數,是一種多執行緒間併發訪問變數的解決方案。和synchronized等加鎖的方式不同,ThreadLocal完全不提供鎖,而使用以空間換時間的方式,為每個執行緒提供變數的獨立副本,以保證執行緒的安全。