中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

大慶開發(fā)網(wǎng)站公司每日新聞

大慶開發(fā)網(wǎng)站公司,每日新聞,網(wǎng)站優(yōu)化系統(tǒng),南京seo按天計(jì)費(fèi)目錄 一、ThreadLocal類基本介紹 1.概述 : 2.作用及特定 : 二、ThreadLocal類源碼解讀 1.代碼準(zhǔn)備 : 1.1 圖示 1.2 數(shù)據(jù)對(duì)象 1.3 測(cè)試類 1.4 運(yùn)行測(cè)試 2.源碼分析 : 2.1 set方法解讀 2.2 get方法解讀 一、ThreadLocal類基本介紹 1.概述 : (1) ThreadLocal,本…

目錄

一、ThreadLocal類基本介紹

? ? ? ? 1.概述 :?

? ? ? ? 2.作用及特定 :?

二、ThreadLocal類源碼解讀

? ? ? ? 1.代碼準(zhǔn)備 :?

? ? ? ? ? ? 1.1 圖示?

? ? ? ? ? ? 1.2 數(shù)據(jù)對(duì)象

? ? ? ? ? ? 1.3 測(cè)試類

? ? ? ? ? ? 1.4 運(yùn)行測(cè)試

? ? ? ? 2.源碼分析 :?

? ? ? ? ? ? 2.1 set方法解讀

? ? ? ? ? ? 2.2 get方法解讀


一、ThreadLocal類基本介紹

? ? ? ? 1.概述 :?

? ? ? ? (1)?ThreadLocal,本地線程變量,是Java中的一個(gè)類。ThreadLocal類提供了一種線程綁定機(jī)制,可以將狀態(tài)與線程(Thread)關(guān)聯(lián)起來(lái)。ThreadLocal類如下圖所示 :?

? ? ? ? (2) 每個(gè)線程都會(huì)有自己獨(dú)立的一個(gè)ThreadLocal變量,該變量對(duì)其他線程而言是封閉且隔離的,因此對(duì)該變量的讀寫操作只會(huì)影響到當(dāng)前執(zhí)行線程的這個(gè)變量,而不會(huì)影響到其他線程的同名變量。

? ? ? ? 2.作用及特定 :?

? ? ? ? (1) ThreadLocal可以實(shí)現(xiàn)在同一個(gè)線程數(shù)據(jù)共享,從而解決多線程數(shù)據(jù)安全問(wèn)題。

? ? ? ? (2) 通過(guò)ThreadLocal類實(shí)例的set方法,可以為當(dāng)前線程關(guān)聯(lián)一個(gè)數(shù)據(jù)(變量,對(duì)象,數(shù)組)

? ? ? ? (3) 通過(guò)ThreadLocal類實(shí)例的get方法,可以像Map一樣存取key-value鍵值對(duì)(其中key為當(dāng)前線程),注意,顯式的用法上與Map不相同。

? ? ? ? (4) 每一個(gè)ThreadLocal對(duì)象,只能為當(dāng)前線程關(guān)聯(lián)一個(gè)數(shù)據(jù),若想為當(dāng)前線程關(guān)聯(lián)多個(gè)數(shù)據(jù),就需要使用到多個(gè)ThreadLocal實(shí)例。

? ? ? ? (5) ThreadLocal實(shí)例往往定義為static類型。

? ? ? ? (6) ThreadLocal中保存的數(shù)據(jù),會(huì)在線程銷毀后自動(dòng)釋放。


二、ThreadLocal類源碼解讀

? ? ? ? 1.代碼準(zhǔn)備 :?

? ? ? ? ? ? 1.1 圖示?

? ? ? ? ? ? ? ? 首先,我們要把代碼打通,確保ThreadLocal對(duì)象可以在同一線程中實(shí)現(xiàn)數(shù)據(jù)共享。根據(jù)下圖來(lái)定義所需要的測(cè)試類 :?

? ? ? ? ? ? ? ? 在T1類,T1Service類,以及T2DAO類中分別打印出當(dāng)前線程的名字,以及放入到threadLocal1對(duì)象中的數(shù)據(jù)對(duì)象,對(duì)比三個(gè)類打印出的線程名字和數(shù)據(jù)對(duì)象是否相同,即可驗(yàn)證“ThreadLocal可以實(shí)現(xiàn)在同一個(gè)線程數(shù)據(jù)共享”。

? ? ? ? ? ? 1.2 數(shù)據(jù)對(duì)象

? ? ? ? ? ? ? ? 定義Apple類和Grape類用作測(cè)試的數(shù)據(jù)對(duì)象。
? ? ? ? ? ? ? ? Apple類代碼如下 :?

package threadlocal;public class Apple {
}

? ? ? ? ? ? ? ? Grape類代碼如下 :?

package threadlocal;/*** @author : Cyan_RA9* @version : 21.0*/
public class Grape {
}

? ? ? ? ? ? 1.3 測(cè)試類

? ? ? ? ? ? ? ? T1類代碼如下 :?

package threadlocal;/*** @author : Cyan_RA9* @version : 21.0*/
public class T1 {//定義一個(gè)靜態(tài)的ThreadLocal對(duì)象public static ThreadLocal<Object> threadLocal1 = new ThreadLocal<>();public static void main(String[] args) {//在主線程中啟動(dòng)一個(gè)新的子線程new Thread(new Task()).start();}public static class Task implements Runnable{@Overridepublic void run() {System.out.println("(Task)run方法,當(dāng)前線程名 = " + Thread.currentThread().getName());Apple apple = new Apple();Grape grape = new Grape();//向threadLocal1對(duì)象中放入一個(gè)Apple對(duì)象System.out.println("(Task)run方法,放入的對(duì)象 = " + apple);threadLocal1.set(apple);new T1Service().test();}}
}

? ? ? ? ? ? ? ? T1Service類代碼如下 :?

package threadlocal;/*** @author : Cyan_RA9* @version : 21.0*/
public class T1Service {public void test() {String name = Thread.currentThread().getName();System.out.println("(T1Service)當(dāng)前線程名 =  " + name);Object o = T1.threadLocal1.get();System.out.println("(T1Service)得到的對(duì)象o = " + o);new T2DAO().test();}
}

? ? ? ? ? ? ? ? T2DAO類代碼如下 :?

package threadlocal;/*** @author : Cyan_RA9* @version : 21.0*/
public class T2DAO {public void test() {String name = Thread.currentThread().getName();System.out.println("(T2DAO)當(dāng)前線程名 = " + name);Object o = T1.threadLocal1.get();System.out.println("(T2DAO)得到的對(duì)象o = " + o);}
}

? ? ? ? ? ? 1.4 運(yùn)行測(cè)試

? ? ? ? ? ? ? ? 運(yùn)行結(jié)果 :?

? ? ? ? 2.源碼分析 :?

? ? ? ? ? ? 2.1 set方法解讀

? ? ? ? ? ? ? ? set方法源碼如下 :?

    public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) {map.set(this, value);} else {createMap(t, value);}}

? ? ? ? ? ? ? ? 第一步,可以看到,set方法中首先就獲取到了當(dāng)前線程,而當(dāng)前線程,就是調(diào)用set方法時(shí)——線程類run方法所在的那個(gè)線程;說(shuō)明set方法和當(dāng)前線程是關(guān)聯(lián)的。
? ? ? ? ? ? ? ? 第二步通過(guò)當(dāng)前線程對(duì)象獲取到了ThreadLocalMap對(duì)象。此處的ThreadLocalMap,是ThreadLocal類的一個(gè)靜態(tài)內(nèi)部類。如下圖所示 :?

? ? ? ? ? ? ? ? 注意,為什么是通過(guò)當(dāng)前線程對(duì)象來(lái)獲取ThreadLocalMap對(duì)象呢?
? ? ? ? ? ? ? ? 因?yàn)楫?dāng)前線程持有自己的ThreadLocal對(duì)象(該對(duì)象調(diào)用了set方法),而ThreadLocalMap又是ThreadLocal的一個(gè)內(nèi)部類.
????????????????
繼續(xù),接著判斷得到的map對(duì)象是否為空,如下圖所示 :?

? ? ? ? ? ? ? ? 如果不為空,就將當(dāng)前的ThreadLocal對(duì)象(this,即指在T1類中一開始調(diào)用set方法的ThreadLocal對(duì)象)和該對(duì)象調(diào)用set方法時(shí)放入的數(shù)據(jù)(value,此處是放入的Apple對(duì)象)。從這里也可以看出,如果同一個(gè)ThreadLocal對(duì)象再次調(diào)用set方法,會(huì)對(duì)存入的數(shù)據(jù)(value)進(jìn)行替換——即"每一個(gè)ThreadLocal對(duì)象,只能為當(dāng)前線程關(guān)聯(lián)一個(gè)數(shù)據(jù)"。
? ? ? ? ? ? ? ? 如果為空,就創(chuàng)建一個(gè)與當(dāng)前線程對(duì)象關(guān)聯(lián)的ThreadLocalMap對(duì)象,并將目標(biāo)數(shù)據(jù)放入(value)。

? ? ? ? ? ? ? ? 在set方法調(diào)用處設(shè)一個(gè)斷點(diǎn),進(jìn)入Debug界面后可以看到當(dāng)前線程對(duì)象名字,如下圖所示 :?

? ? ? ? ? ? ? ? 在this對(duì)象中向下找,可以找到一個(gè)threadLocals屬性,發(fā)現(xiàn)它就是ThreadLocalMap類型,如下圖所示 :?

? ? ? ? ? ? ? ? 我們也可以Thread類的源碼中找到這個(gè)屬性,如下圖所示 :

? ? ? ? ? ? ? ? 而該屬性下的table, 就是實(shí)際存放數(shù)據(jù)的地方(可以看到table是ThreadLocalMap的內(nèi)部類Entry類型的數(shù)組)。當(dāng)set方法執(zhí)行完畢后,我們可以看到table數(shù)組中的Apple對(duì)象,如下圖所示 :

? ? ? ? ? ? ? ? 實(shí)際上,table就是線程用于管理ThreadLocal實(shí)例的容器。
????????????????而table數(shù)組中每個(gè)元素的referent屬性(弱引用對(duì)象),也就是ThreadLocal對(duì)象,此處可以看到與之前一致,如下?:?

? ? ? ? ? ? 2.2 get方法解讀

? ? ? ? ? ? ? ? get方法源碼如下 : (PS : 注意此處是泛型在方法上的應(yīng)用,而不是自定義泛型方法)

    public T get() {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) {ThreadLocalMap.Entry e = map.getEntry(this);if (e != null) {@SuppressWarnings("unchecked")T result = (T)e.value;return result;}}return setInitialValue();}

? ? ? ? ? ? ? ? 第一步,和set方法一樣,都是先得到當(dāng)前的線程對(duì)象。為啥?因?yàn)橹挥械玫搅水?dāng)前線程對(duì)象,才能找到它的屬性threadLocals[ThreadLocal$ThreadLocalMap類型],繼而找到該屬性維護(hù)的table數(shù)組(ThreadLocal$ThreadLocalMap$Entry[]類型),然后根據(jù)當(dāng)前線程持有的的ThreadLocal實(shí)例,找到數(shù)組中對(duì)應(yīng)的Entry元素,繼而拿到它的屬性value(保存的數(shù)據(jù))
? ? ? ? ? ? ? ? 顯然,get方法的源碼中也的確是這么干的。通過(guò)當(dāng)前線程對(duì)象拿到ThreadLocalMap對(duì)象,我們可以看一下getMap(t)的源碼,如下圖所示 :

????????????????之后,判斷map對(duì)象是否為空,如果不為空,就根據(jù)當(dāng)前持有的ThreadLocal實(shí)例去找table數(shù)組中對(duì)應(yīng)的Entry元素。繼續(xù)往下走?:?

? ? ? ? ? ? ? ? 拿到對(duì)應(yīng)的Entry元素后,還要進(jìn)行判斷,如果該元素的確是存在的(表明當(dāng)前的ThreadLocal實(shí)例已經(jīng)為當(dāng)前線程綁定過(guò)數(shù)據(jù)[一個(gè)value]), 就取出該Entry元素的value屬性,此處為Object類型的apple對(duì)象,然后返回。

? ? ? ? ? ? ? ? 🆗,以上就是對(duì)ThreadLocal的一些淺顯解讀。感謝閱讀!

http://www.risenshineclean.com/news/55104.html

相關(guān)文章:

  • 怎么注冊(cè)網(wǎng)站賬號(hào)seo查詢
  • 哈爾濱網(wǎng)站建設(shè)信息網(wǎng)站如何做優(yōu)化排名
  • 現(xiàn)成的手機(jī)網(wǎng)站做APP最近實(shí)時(shí)熱點(diǎn)事件
  • 培訓(xùn)網(wǎng)站建設(shè)永州網(wǎng)站seo
  • 網(wǎng)站建設(shè)入門教程對(duì)網(wǎng)絡(luò)營(yíng)銷的認(rèn)識(shí)800字
  • 網(wǎng)頁(yè)工具東莞優(yōu)化排名公司
  • 農(nóng)業(yè)網(wǎng)站建設(shè)方案 ppt搜索推廣平臺(tái)
  • 有什么網(wǎng)站是做平面設(shè)計(jì)的百度搜索的優(yōu)勢(shì)
  • 真人性做爰video網(wǎng)站公司網(wǎng)站建站要多少錢
  • 深圳做積分商城網(wǎng)站建設(shè)怎么制作鏈接網(wǎng)頁(yè)
  • 深圳分銷網(wǎng)站設(shè)計(jì)電話企業(yè)網(wǎng)站建設(shè)
  • 公司建一個(gè)網(wǎng)站嗎搜什么關(guān)鍵詞能搜到好片
  • 廣州知名網(wǎng)站建設(shè)哪家公司好seo文案范例
  • 產(chǎn)品網(wǎng)站建設(shè)軟文推廣營(yíng)銷平臺(tái)
  • 家里電腦做網(wǎng)站服務(wù)器seo推廣怎么樣
  • 網(wǎng)站開發(fā)什么意思徐州seo公司
  • 河南新鄉(xiāng)市建設(shè)銀行網(wǎng)站系統(tǒng)優(yōu)化軟件排行榜
  • 競(jìng)價(jià)網(wǎng)站做seo教育培訓(xùn)機(jī)構(gòu)官網(wǎng)
  • 武漢網(wǎng)絡(luò)推廣有哪些公司鄂爾多斯seo
  • 湛江找人做網(wǎng)站排名球隊(duì)排名榜實(shí)時(shí)排名
  • 網(wǎng)站建設(shè)中 html營(yíng)銷課程
  • 做網(wǎng)站如何設(shè)計(jì)數(shù)據(jù)庫(kù)個(gè)人網(wǎng)頁(yè)設(shè)計(jì)作品模板
  • wordpress .htaccess 規(guī)則seo代碼優(yōu)化工具
  • 門戶網(wǎng)站功能清單萬(wàn)網(wǎng)域名查詢注冊(cè)商
  • 做的很好的黑白網(wǎng)站如何在百度上做產(chǎn)品推廣
  • 西寧網(wǎng)站設(shè)計(jì)公司seo外鏈平臺(tái)
  • 網(wǎng)站 國(guó)外空間不需要icp許可證嗎推廣引流吸引人的文案
  • 成都網(wǎng)站推廣排名怎么把自己的網(wǎng)站發(fā)布到網(wǎng)上
  • 官方網(wǎng)站建設(shè)報(bào)價(jià)怎么讓百度快速收錄網(wǎng)站
  • 古冶區(qū)城鄉(xiāng)建設(shè)局網(wǎng)站seo技術(shù)培訓(xùn)江門