日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
詳細(xì)介紹ThreadLocal

JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal為解決多線程程序的并發(fā)問題提供了一種新的思路。使用這個(gè)工具類可以很簡潔地編寫出優(yōu)美的多線程程序,ThreadLocal并不是一個(gè)Thread,而是Thread的局部變量。

我們提供的服務(wù)有:網(wǎng)站建設(shè)、網(wǎng)站制作、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、奈曼ssl等。為上千家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的奈曼網(wǎng)站制作公司

一、ThreadLocal概述

學(xué)習(xí)JDK中的類,首先看下JDK API對(duì)此類的描述,描述如下:

JDK API 寫道

該類提供了線程局部 (thread-local) 變量。這些變量不同于它們的普通對(duì)應(yīng)物,因?yàn)樵L問某個(gè)變量(通過其 get 或 set 方法)的每個(gè)線程都有自己的局部變量,它獨(dú)立于變量的初始化副本。ThreadLocal 實(shí)例通常是類中的 private static 字段,它們希望將狀態(tài)與某一個(gè)線程(例如,用戶 ID 或事務(wù) ID)相關(guān)聯(lián)。

API表達(dá)了下面幾種觀點(diǎn):

1、ThreadLocal不是線程,是線程的一個(gè)變量,你可以先簡單理解為線程類的屬性變量。

2、ThreadLocal 在類中通常定義為靜態(tài)類變量。

3、每個(gè)線程有自己的一個(gè)ThreadLocal,它是變量的一個(gè)‘拷貝’,修改它不影響其他線程。

既然定義為類變量,為何為每個(gè)線程維護(hù)一個(gè)副本(姑且成為‘拷貝’容易理解),讓每個(gè)線程獨(dú)立訪問?多線程編程的經(jīng)驗(yàn)告訴我們,對(duì)于線程共享資源(你可以理解為屬性),資源是否被所有線程共享,也就是說這個(gè)資源被一個(gè)線程修改是否影響另一個(gè)線程的運(yùn)行,如果影響我們需要使用synchronized同步,讓線程順序訪問。

ThreadLocal適用于資源共享但不需要維護(hù)狀態(tài)的情況,也就是一個(gè)線程對(duì)資源的修改,不影響另一個(gè)線程的運(yùn)行;這種設(shè)計(jì)是‘空間換時(shí)間’,synchronized順序執(zhí)行是‘時(shí)間換取空間’。

二、ThreadLocal方法介紹

  • T get()  返回此線程局部變量的當(dāng)前線程副本中的值。
  • protected T initialValue()  返回此線程局部變量的當(dāng)前線程的“初始值”。
  • void remove()  移除此線程局部變量當(dāng)前線程的值。
  • void set(T value)  將此線程局部變量的當(dāng)前線程副本中的值設(shè)置為指定值。

三、深入源碼

ThreadLocal有一個(gè)ThreadLocalMap靜態(tài)內(nèi)部類,你可以簡單理解為一個(gè)MAP,這個(gè)‘Map’為每個(gè)線程復(fù)制一個(gè)變量的‘拷貝’存儲(chǔ)其中。

當(dāng)線程調(diào)用ThreadLocal.get()方法獲取變量時(shí),首先獲取當(dāng)前線程引用,以此為key去獲取響應(yīng)的ThreadLocalMap,如果此‘Map’不存在則初始化一個(gè),否則返回其中的變量,代碼如下:

Get方法代碼 :

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

調(diào)用get方法如果此Map不存在首先初始化,創(chuàng)建此map,將線程為key,初始化的vlaue存入其中,注意此處的initialValue,我們可以覆蓋此方法,在首次調(diào)用時(shí)初始化一個(gè)適當(dāng)?shù)闹?。setInitialValue代碼如下:

Java代碼

 
 
  1. private T setInitialValue() {  
  2. T value = initialValue();  
  3. Thread t = Thread.currentThread();  
  4. ThreadLocalMap map = getMap(t);  
  5. if (map != null)  
  6. map.set(this, value);  
  7. else 
  8. createMap(t, value);  
  9. return value;  
  10. }  

set方法相對(duì)比較簡單如果理解以上倆個(gè)方法,獲取當(dāng)前線程的引用,從map中獲取該線程對(duì)應(yīng)的map,如果map存在更新緩存值,否則創(chuàng)建并存儲(chǔ),代碼如下:

Java代碼:

 
 
  1. public void set(T value) {  
  2. Thread t = Thread.currentThread();  
  3. ThreadLocalMap map = getMap(t);  
  4. if (map != null)  
  5. map.set(this, value);  
  6. else 
  7. createMap(t, value);  
  8. }  

對(duì)于ThreadLocal在何處存儲(chǔ)變量副本,我們看getMap方法:獲取的是當(dāng)前線程的ThreadLocal類型的threadLocals屬性。顯然變量副本存儲(chǔ)在每一個(gè)線程中。

Java代碼 :

 
 
  1. /**  
  2. * 獲取線程的ThreadLocalMap 屬性實(shí)例  
  3. */ 
  4. ThreadLocalMap getMap(Thread t) {  
  5. return t.threadLocals;  

上面我們知道變量副本存放于何處,這里我們簡單說下如何被java的垃圾收集機(jī)制收集,當(dāng)我們不在使用是調(diào)用set(null),此時(shí)不在將引用指向該‘map’,而線程退出時(shí)會(huì)執(zhí)行資源回收操作,將申請(qǐng)的資源進(jìn)行回收,其實(shí)就是將屬性的引用設(shè)置為null。這時(shí)已經(jīng)不在有任何引用指向該map,故而會(huì)被垃圾收集。

希望通過本文對(duì)hreadLocal的介紹,能夠給你帶來幫助。


網(wǎng)站題目:詳細(xì)介紹ThreadLocal
URL鏈接:http://www.5511xx.com/article/djpggjp.html