-
ThreadLocal是線程的局部變量, 是每一個線程所單獨持有的,其他線程不能對其進行訪問
-
ThreadLocal支持泛型,也就是支持value是可以設置類型的,像是
ThreadLocal<Date>
就是設置value爲Date類型 -
每個線程會有自己的一份ThreadLocalMap變量,去儲存這個線程自己想存放的ThreadLocal變量們,他內部儲存的是一個鍵值對Map,其中key是某個ThreadLocal,value就是這個線程自己set的值,所以對於一個線程來說,一個ThreadLocal只能存一個值,而一個線程可以存放好多個ThreadLocal
-
因此當調用ThreadLocal
tl
的tl.get()
方法時,其實就是先去取得此線程的ThreadLocalMap,然後再去查找這個Map中的key爲tl
的那個Entry的value值
-
-
ThreadLocal常用的方法
-
set(x)
: 設置此線程的想要放的值是多少 -
get()
: 取得此線程當初存放的值,如果沒有存放過則返回null -
remove()
: 刪除此線程的鍵值對,也就是如果先執行remove再執行get,會返回null
-
-
ThreadLocal通常用在SimpleDateFormat,或是SpringMVC上
-
因爲SimpleDateFormat不是線程安全的,因此雖然可以每次要使用的時候重新
new
一個,但是這樣做會很浪費資源,所以如果使用ThreadLocal在每個線程裡都存放一個此線程專用的SimpleDateFormat,就可以避免一直new
的資源浪費,又確保線程安全 -
因爲SpringMVC會對每個請求分配一個線程,可以在攔截器將此線程的用戶信息(ip、名字...)使用ThreadLocal儲存,這樣在後續要用到用戶信息的地方時,就可以去ThreadLocal中取得,而且因爲ThreadLocal可以隔離線程,因此每條請求對應的線程的用戶信息不會互相干擾
-
-
具體實例
-
每個線程都可以在ThreadLocal中放自己的值,且不會干擾到其他線程的值
class Tools { public static ThreadLocal threadLocal = new ThreadLocal(); } class MyThread extends Thread { @Override public void run() { if (Tools.threadLocal.get() == null) { Tools.threadLocal.set(Thread.currentThread().getName() + ", " + Math.random()); } System.out.println(Tools.threadLocal.get()); } } public class Main { public static void main(String[] args) { for (int i = 0; i < 5; i++) { MyThread thread = new MyThread(); thread.setName("thread " + i); thread.start(); } } }
Tools { public static ThreadLocal threadLocal = new ThreadLocal(); } class MyThread extends Thread { @Override public void run() { if (Tools.threadLocal.get() == null) { Tools.threadLocal.set(Thread.currentThread().getName() + ", " + Math.random()); } System.out.println(Tools.threadLocal.get()); } } public class Main { public static void main(String[] args) { for (int i = 0; i < 5; i++) { MyThread thread = new MyThread(); thread.setName("thread " + i); thread.start(); } } }thread 1, 0.86 thread 0, 0.42 thread 2, 0.35 thread 3, 0.41 thread 4, 0.45
thread 0, 0.42 thread 2, 0.35 thread 3, 0.41 thread 4, 0.45 -
使用ThreadLocal在SimpleDateFormat上,並且給ThreadLocal加上泛型,指定value的類型是SimpleDateFormat
-
因爲使用了ThreadLocal確保每個線程有自己一份SimpleDateFormat,所以線程安全,不會報錯
class Tools { public static ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>(); } class MyThread extends Thread { @Override public void run() { SimpleDateFormat sdf = Tools.threadLocal.get(); if (sdf == null) { sdf = new SimpleDateFormat("yyyy-MM-dd"); Tools.threadLocal.set(sdf); } try { System.out.println(sdf.parse("2018-07-15")); } catch (ParseException e) { System.out.println("報錯了"); } } } public class Main { public static void main(String[] args) { for (int i = 0; i < 5; i++) { MyThread thread = new MyThread(); thread.setName("thread " + i); thread.start(); } } }
Tools { public static ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>(); } class MyThread extends Thread { @Override public void run() { SimpleDateFormat sdf = Tools.threadLocal.get(); if (sdf == null) { sdf = new SimpleDateFormat("yyyy-MM-dd"); Tools.threadLocal.set(sdf); } try { System.out.println(sdf.parse("2018-07-15")); } catch (ParseException e) { System.out.println("報錯了"); } } } public class Main { public static void main(String[] args) { for (int i = 0; i < 5; i++) { MyThread thread = new MyThread(); thread.setName("thread " + i); thread.start(); } } }Sun Jul 15 00:00:00 CST 2018 Sun Jul 15 00:00:00 CST 2018 Sun Jul 15 00:00:00 CST 2018 Sun Jul 15 00:00:00 CST 2018 Sun Jul 15 00:00:00 CST 2018
Sun Jul 15 00:00:00 CST 2018 Sun Jul 15 00:00:00 CST 2018 Sun Jul 15 00:00:00 CST 2018 Sun Jul 15 00:00:00 CST 2018 -
-
Java多線程 - ThreadLocal類的使用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.