ThreadLocal了解使用
1.threadlocal是一種多線程間并發通路變量的解決方案,采取以空間換時間的方式,不使用鎖,為每個線程提供變量的獨立副本,以保障線程安全
2.背景:變量分為類變量 執行個體變量和局部變量(局部變量是線程安全的不用考慮)
情景一:ThreadLocal存儲類變量的時候存線上程安全問題,所有線程共享類變量,變量的改變會導緻所有線程副本變量的改變
private ThreadLocal local =new ThreadLocal();
private static List<String> list=new ArrayList<>();
public void setName(String name) {
list.add(name);
list.add("test");
//因為在main方法裡面運作是以注意區分主線程和子線程(ThreadLocal和線程綁定的)
// local.set(list);(這裡使用隻能是主線程ThreadLocal綁定了list)
System.out.println(Thread.currentThread());
}
@Override
public void run() {
local.set(list);
System.out.println(local.get());
System.out.println(Thread.currentThread());
}
//運作
public static void main(String[] asd){
local al = new local();
Thread thread =new Thread(new local());
Thread thread1=new Thread(new local());
try {
Thread.sleep(1000);
al.setName("123");
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.start();
thread1.start();
System.out.println(Thread.currentThread());
結果:[123, test]
[123, test]
情景二:ThreadLocal存儲的是實力變得時候也會存線上程安全問題,當多個線程處理同一個執行個體變量的時候,執行個體變量的變化會導緻多個線程的執行個體副本都會發生變化,如果一個線程處理一個執行個體就不會發生安全問題,并且保證執行個體變量副本的修改互不影響。
private ThreadLocal local =new ThreadLocal();
private List<String> list=new ArrayList<>();
public void setName(String name) {
list.add(name);
list.add("test");
//因為在main方法裡面運作是以注意區分主線程和子線程(ThreadLocal和線程綁定的)
// local.set(list);(這裡使用隻能是主線程ThreadLocal綁定了list)
System.out.println(Thread.currentThread());
}
@Override
public void run() {
local.set(list);
System.out.println(local.get());
System.out.println(Thread.currentThread());
}
//運作
public static void main(String[] asd){
local al = new local();
Thread thread =new Thread(al);
Thread thread1=new Thread(al);
try {
Thread.sleep(1000);
al.setName("123");
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.start();
thread1.start();
System.out.println(Thread.currentThread());
結果:[123, test]
[123, test]
備注:重點是厘清楚主線程(目前線程,例如Thread.sleep就是指的是目前線程也就是代碼正在運作所線上程)和子線程