成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳細介紹ThreadLocal

開發 后端
ThreadLocal和java線程有關,不過它并不是java線程的一個實現,它只是用來維護本地變量。本文詳細介紹了ThreadLocal,希望對你有幫助。

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

一、ThreadLocal概述

學習JDK中的類,首先看下JDK API對此類的描述,描述如下:

JDK API 寫道

該類提供了線程局部 (thread-local) 變量。這些變量不同于它們的普通對應物,因為訪問某個變量(通過其 get 或 set 方法)的每個線程都有自己的局部變量,它獨立于變量的初始化副本。ThreadLocal 實例通常是類中的 private static 字段,它們希望將狀態與某一個線程(例如,用戶 ID 或事務 ID)相關聯。

API表達了下面幾種觀點:

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

2、ThreadLocal 在類中通常定義為靜態類變量。

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

 

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

 

ThreadLocal適用于資源共享但不需要維護狀態的情況,也就是一個線程對資源的修改,不影響另一個線程的運行;這種設計是‘空間換時間’,synchronized順序執行是‘時間換取空間’。

 

二、ThreadLocal方法介紹

 

 

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

 

三、深入源碼

ThreadLocal有一個ThreadLocalMap靜態內部類,你可以簡單理解為一個MAP,這個‘Map’為每個線程復制一個變量的‘拷貝’存儲其中。

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

 

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. }  

 

調用get方法如果此Map不存在首先初始化,創建此map,將線程為key,初始化的vlaue存入其中,注意此處的initialValue,我們可以覆蓋此方法,在首次調用時初始化一個適當的值。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方法相對比較簡單如果理解以上倆個方法,獲取當前線程的引用,從map中獲取該線程對應的map,如果map存在更新緩存值,否則創建并存儲,代碼如下:

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. }  

 

對于ThreadLocal在何處存儲變量副本,我們看getMap方法:獲取的是當前線程的ThreadLocal類型的threadLocals屬性。顯然變量副本存儲在每一個線程中。

 

Java代碼 :

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

 

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

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

責任編輯:于鐵 來源: ITEYE
相關推薦

2011-07-14 14:15:40

ThreadLocal

2022-08-26 07:33:49

內存JVMEntry

2023-05-29 07:17:48

內存溢出場景

2011-03-15 09:14:29

2009-09-08 13:07:15

介紹Linq to S

2011-06-21 14:42:37

ECMAScriptJavaScript

2009-06-29 14:30:27

JSF技術

2009-07-07 17:01:09

MyServlet

2009-09-18 09:25:06

LINQ Framew

2009-06-19 14:49:43

Spring框架

2024-10-28 08:15:32

2009-11-09 17:30:20

WCF元數據

2009-12-15 17:05:59

.NET 2003

2010-01-05 16:56:28

2009-08-31 08:42:44

思科認證思科認證CCNA認證

2011-07-04 17:59:03

開閉原則

2011-07-04 18:16:42

單元測試

2011-07-12 18:02:00

PHP

2010-06-23 15:36:23

Linux Bug B

2011-08-18 10:06:10

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91亚洲欧美 | 亚洲高清一区二区三区 | 久久久久国产 | 91在线精品视频 | 国产精品久久久久久久久久久久午夜片 | 成人av网站在线观看 | 欧美日产国产成人免费图片 | 一区二区三区成人 | 婷婷激情综合 | 中文字幕在线播放第一页 | wwww.xxxx免费 | 伊人春色在线观看 | 精品国产一区二区三区日日嗨 | 本道综合精品 | 中文字幕 欧美 日韩 | 亚洲欧美激情精品一区二区 | 一级全黄少妇性色生活免费看 | jav成人av免费播放 | 亚洲国产69| 欧美电影大全 | 国产日韩欧美一区 | 99精品欧美一区二区三区 | 久久91av| 国产欧美日韩在线观看 | 草久久久 | 欧美9999 | 男人天堂色 | av性色| 久久久久久免费毛片精品 | 国产在线资源 | 精品亚洲一区二区三区 | 国产精品久久久久久久久久久久久久 | 免费的黄色片子 | 日韩视频在线一区 | 日本亚洲欧美 | 天天干夜夜操视频 | 久久成人免费视频 | 国产精品美女视频 | 美女视频.| 亚洲成人播放器 | 九九亚洲 |