ThreadLocal詳解(實現多線程同步訪問變量)

ThreadLocal翻譯成中文比較準確的叫法應該是:線程局部變量。

  這個玩意有什么用處,或者說為什么要有這么一個東東?先解釋一下,在并發編程的時候,成員變量如果不做任何處理其實是線程不安全的,各個線程都 在操作同一個變量,顯然是不行的,并且我們也知道volatile這個關鍵字也是不能保證線程安全的。那么在有一種情況之下,我們需要滿足這樣一個條件: 變量是同一個,但是每個線程都使用同一個初始值,也就是使用同一個變量的一個新的副本。這種情況之下ThreadLocal就非常使用,比如說DAO的數 據庫連接,我們知道DAO是單例的,那么他的屬性Connection就不是一個線程安全的變量。而我們每個線程都需要使用他,并且各自使用各自的。這種 情況,ThreadLocal就比較好的解決了這個問題。

  我們從源碼的角度來分析這個問題。

  首先定義一個ThreadLocal:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ConnectionUtil {
????private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
????private static Connection initConn = null;
????static {
????????try {
????????????initConn = DriverManager.getConnection("url, name and password");
????????} catch (SQLException e) {
????????????e.printStackTrace();
????????}
????}
?????
????public Connection getConn() {
????????Connection c = tl.get();
????????tl.set(initConn);
????????return c;
????}
?????
}

  這樣子,都是用同一個連接,但是每個連接都是新的,是同一個連接的副本。

  那么實現機制是如何的呢?

  1、每個Thread對象內部都維護了一個ThreadLocalMap這樣一個ThreadLocal的Map,可以存放若干個ThreadLocal。

1
2
3
/* ThreadLocal values pertaining to this thread. This map is maintained
?* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;

  2、當我們在調用get()方法的時候,先獲取當前線程,然后獲取到當前線程的ThreadLocalMap對象,如果非空,那么取出ThreadLocal的value,否則進行初始化,初始化就是將initialValue的值set到ThreadLocal中。

1
2
3
4
5
6
7
8
9
10
public T get() {
????Thread t = Thread.currentThread();
????ThreadLocalMap map = getMap(t);
????if (map != null) {
????????ThreadLocalMap.Entry e = map.getEntry(this);
????????if (e != null)
????????????return (T)e.value;
????}
????return setInitialValue();
}

  3、當我們調用set()方法的時候,很常規,就是將值設置進ThreadLocal中。

  4、總結:當我們調用get方法的時候,其實每個當前線程中都有一個ThreadLocal。每次獲取或者設置都是對該ThreadLocal進行的操作,是與其他線程分開的。

  5、應用場景:當很多線程需要多次使用同一個對象,并且需要該對象具有相同初始化值的時候最適合使用ThreadLocal。

  6、其實說再多也不如看一下源碼來得清晰。如果要看源碼,其中涉及到一個WeakReference和一個Map,這兩個地方需要了解下,這兩 個東西分別是a.Java的弱引用,也就是GC的時候會銷毀該引用所包裹(引用)的對象,這個threadLocal作為key可能被銷毀,但是只要我們 定義成他的類不卸載,tl這個強引用就始終引用著這個ThreadLocal的,永遠不會被gc掉。b.和HashMap差不多。

  事實上,從本質來講,就是每個線程都維護了一個map,而這個map的key就是threadLocal,而值就是我們set的那個值,每次線 程在get的時候,都從自己的變量中取值,既然從自己的變量中取值,那肯定就不存在線程安全問題,總體來講,ThreadLocal這個變量的狀態根本沒 有發生變化,他僅僅是充當一個key的角色,另外提供給每一個線程一個初始值。如果允許的話,我們自己就能實現一個這樣的功能,只不過恰好JDK就已經幫 我們做了這個事情。

轉載于:https://www.cnblogs.com/Berryxiong/p/6220545.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371774.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371774.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371774.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SCREEN屏幕編程時候必須保證SCREN中詞典的字段格式必須和數據表中字段的類型長度一致!...

此時任意操作都會出現如下問題 /h調試 回車調試被激活任意操作 執行到第23行時候報錯“請輸入一個數值”&#xff0c;檢查數據表中字段參考數據元素以及對應的域均是char類型&#xff0c;此時檢查screen屏幕設置字段類型&#xff0c;/n退出程序 重新進入程序 單擊 點擊屏幕9000…

mysql 阿里云 版本_關于阿里云centos版本,mysql5.7的一些注意事項

1.阿里云進去mysql是默認已經安裝好了的&#xff0c;只需要修改root用戶的密碼。關于修改密碼&#xff1a;1)登陸阿里云&#xff0c;進入root目錄&#xff0c;會有mysql的.sh文件&#xff0c;可以通過運行該文件得到初始密碼。此時用初始密碼登陸mysql&#xff0c;use mysql 切…

JAXB –不需要注釋

似乎存在一個誤解&#xff0c;認為在模型上需要使用批注才能使用JAXB&#xff08;JSR-222&#xff09;實現。 事實是&#xff0c;JAXB是例外配置&#xff0c;因此僅當您要覆蓋默認行為時才需要注釋。 在此示例中&#xff0c;我將演示如何在不提供任何元數據的情況下使用JAXB。 …

zabbix 3.0.3 (nginx)安裝過程中的問題排錯記錄

特殊注明&#xff1a;安裝zabbix 2.4.8和2.4.6遇到2個問題&#xff0c;如下&#xff1a;找了很多解決辦法&#xff0c;實在無解&#xff0c;只能換版本&#xff0c;嘗試換&#xff08;2.2.2正常 | 3.0.3正常&#xff09;都正常&#xff0c;最后決定換3.0.31、Error connecting …

安裝mysql5.7.24rpm_centos7安裝mysql-5.7.24(rpm安裝)

關于mysql的4個rpm包node[rootelk-200 ~]# ls mysql/ -lhtotal 192M-rw-r--r-- 1 root root 25M Aug 26 12:38 mysql-community-client-5.7.24-1.el7.x86_64.rpm-rw-r--r-- 1 root root 275K Aug 26 12:38 mysql-community-common-5.7.24-1.el7.x86_64.rpm-rw-r--r-- 1 root ro…

Java鎖實現

我們都使用第三方庫作為開發的正常部分。 通常&#xff0c;我們無法控制其內部。 JDK隨附的庫是一個典型示例。 這些庫中的許多庫都使用鎖來管理競爭。 JDK鎖具有兩種實現。 人們使用原子CAS樣式指令來管理索賠過程。 CAS指令往往是最昂貴的CPU指令類型&#xff0c;并且在x86上…

一鍵生成APP官網

只需要輸入蘋果下載地址&#xff0c;安卓市場下載地址&#xff0c;或者內測下載地址&#xff0c;就能一鍵生成APP的官網&#xff0c;方便在網上推廣。 好推APP官網 www.hotapp.cn/app 轉載于:https://www.cnblogs.com/likwo/p/6223889.html

python 字符ab+字符c 2_“ab”+”c”*2 結果是: (1.3分)_學小易找答案

【判斷題】藥物效應動力學簡稱藥效學,是研究藥物對機體的作用?【單選題】以下關于Python語言中“縮進”說法正確的是:?????????????????????????????????????????????????????????????????????????…

數據結構及算法 -- 目錄

排序算法 -- 目錄 啦啦啦轉載于:https://www.cnblogs.com/ClassNotFoundException/p/7122848.html

Spring MVC集成測試

在Spring MVC中對控制器進行集成測試的一種方法是使用Spring提供的集成測試支持。 對于Junit4&#xff0c;此支持包括一個名為SpringJunit4ClassRunner的自定義Junit Runner和一個用于加載相關Spring配置的自定義批注。 樣本集成測試將遵循以下原則&#xff1a; RunWith(Spri…

spark 快速入門 java API

Spark的核心就是RDD&#xff0c;對SPARK的使用入門也就是對RDD的使用&#xff0c;包括action和transformation 對于Java的開發者&#xff0c;單單看文檔根本是沒有辦法理解每個API的作用的&#xff0c;所以每個SPARK的新手&#xff0c;最好按部就班直接學習scale, 那才是一個高…

網頁設計上機考試原題_Dreamweaver上機考試題目dreamweaver試題庫網頁制作試題.doc...

網頁設計上機考試題集注意&#xff1a;所有題目中涉及的素材都在考試文件夾內&#xff0c;其中圖片在下面的pic文件夾中&#xff0c;音樂、flash在media文件夾。1) 在1.html中的頂部添加一個錨點鏈接&#xff0c;點擊之能立即到達頁面最底端。2) 將1.html中的所有鏈接的默認樣式…

35數據結構與算法分析之---最短路徑

本系列是閱讀《數據結構與算法應用實踐教程》第2版 主編 李文書 北京大學出版社 的讀書筆記&#xff0c;加上自己的理解&#xff0c;更多的是學習的記錄與反思&#xff0c;如有不妥&#xff0c;歡迎指正&#xff0c;非常感謝。轉載于:https://www.cnblogs.com/guochaoxxl/p/712…

Quartz 2 Scheduler示例

Quartz是一個開源作業調度框架。 它可用于管理和計劃應用程序中的作業。 步驟1&#xff1a;建立已完成的專案 創建一個Maven項目&#xff0c;如下所示。 &#xff08;可以使用Maven或IDE插件來創建它&#xff09;。 步驟2&#xff1a;圖書館 Quartz依賴項已添加到Maven的po…

sql server 2008 com.microsoft.sqlserver.jdbc.SQLServerException: 通過端口 1433 連接到主機

原內容搬遷到了新網站&#xff0c;給你帶來的不便&#xff0c;敬請諒解&#xff01; 》 http://www.suanliutudousi.com/2017/08/28/sql-server-2008-com-microsoft-sqlserver-jdbc-sqlserverexception-%E9%80%9A%E8%BF%87%E7%AB%AF%E5%8F%A3-1433-%E8%BF%9E%E6%8E%A5%E5%88%B0…

如何通過網線連接兩臺電腦快速傳輸數據?

介紹 我們經常需要拷貝文件會用到類似U盤等工具&#xff0c;但我們有時在傳輸大文件時又苦于沒有&#xff0c;那么大內存的轉存工具。這時候我們就可以通過一條小小的網線連接兩臺電腦&#xff0c;形成一個小的局域網傳輸數據&#xff0c;因為是通過網線傳輸&#xff0c;所以傳…

30分鐘內使用MongoDB

最近&#xff0c;我被NoSQL錯誤咬住了-或是我的同事Mark Atwell提出的“燃燒在哪里&#xff01;” 運動。 盡管我無意于在不久的將來或可預見的將來回避友好的“ SELECT ... WHERE”&#xff0c;但我確實設法弄懂了一些代碼。 在本文中&#xff0c;我分享了我在NoSQL世界中首次…

【Django】--ModelForm組件

ModelForm a.class Meta:model,#對應Model的  fieldsNone,#字段  excludeNone,#排除字段  labelsNone,#提示信息  help_texts None,#幫助提示信息  widgets None,#自定義插件  error_messages None,#自定義錯誤信息(整體錯誤信息from django.core.exceptions im…

mysql實際綜合案例_Mysql綜合案例

Mysql綜合案例考核要點&#xff1a;創建數據表、單表查詢、多表查詢已知&#xff0c;有一個學生表student和一個分數表score&#xff0c;請按要求對這兩個表進行操作。student表和score分數表的表結構分別如表1-1和表1-2所示。表1-1student表結構字段名數據類型主鍵外鍵非空唯一…

2012年I / O之后

從注冊到贈品&#xff0c;每年的I / O瘋狂都在不斷發展。 在今年20分鐘內被出售&#xff0c;并沒有阻止Google贈送更多的東西。 以這種速度并有望在明年發布Google Glass&#xff0c;明年注冊很可能會變得更加混亂&#xff01; 因此&#xff0c;Google&#xff0c;請停止提供免…