成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Java并發(fā)編程——ThreadLocal

ThreadLocal

創(chuàng)新互聯(lián)長期為超過千家客戶提供的網(wǎng)站建設服務,團隊從業(yè)經(jīng)驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為興山企業(yè)提供專業(yè)的成都網(wǎng)站建設、網(wǎng)站制作,興山網(wǎng)站改版等技術服務。擁有10多年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。

概述

一、對ThreadLocal的理解

1.1 ThreadLocal在JDK中的定義

1.2 應用場景

二、深入分析ThreaLocal類

2.1 get()

2.2 setIntialValue()

2.3 ThreadLocal類是如何為每個線程創(chuàng)建變量副本

三、ThreadLocal的應用場景

3.1 數(shù)據(jù)庫連接問題

3.2 Session管理

3.3 Thread-per-Request(一個請求對應一個服務器線程)

四、ThreadLocal的一般使用步驟

概述

本文借鑒了Java 并發(fā)編程這篇博主專欄的文章,他的專欄寫的很好,推薦!

ThreadLocal 又名 線程局部變量 ,是 Java 中一種較為特殊的線程綁定機制,可以為每一個使用該變量的線程都提供一個變量值的副本,并且每一個線程都可以獨立地改變自己的副本,而不會與其它線程的副本發(fā)生沖突。

一般而言,通過 ThreadLocal 存取的數(shù)據(jù)總是與當前線程相關,也就是說,JVM 為每個運行的線程綁定了私有的本地實例存取空間,從而為多線程環(huán)境常出現(xiàn)的并發(fā)訪問問題提供了一種 隔離機制 。

如果某個變量要被某個線程獨享,那么我們就可以通過ThreadLocal來實現(xiàn)本地存儲功能;

一、對ThreadLocal的理解

1.1 ThreadLocal在JDK中的定義

每個線程都有關于該 ThreadLocal變量 的私有值 ,并且對其他線程是不可見的;

ThreadLocal 可以給定一個獨立于變量的初始值,這樣每個線程就會獲得這個初始化值的一個拷貝,并且每個線程對這個值的修改對其他線程是不可見的;

ThreadLocal的一個重要作用是就是將類的狀態(tài)與線程關聯(lián)起來,解決方案就是在這個類中定義一個 private static ThreadLocal 實例;

1.2 應用場景

類 ThreadLocal 主要解決的就是為每個線程綁定自己的值,以方便其處理自己的狀態(tài);

形象地講,可以將 ThreadLocal變量 比喻成全局存放數(shù)據(jù)的盒子,盒子中可以存儲每個線程的私有數(shù)據(jù)。例如,以下類用于生成對每個線程唯一的局部標識符。線程 ID 是在第一次調用 uniqueNum.get() 時分配的,在后續(xù)調用中不會更改;

二、深入分析ThreaLocal類

ThreadLocal中,一共提供了四個方法:

public T get() { }

public void set(T value){ }

public void remove(){ }

protected T initialValue{ }

1

2

3

4

get() 獲取ThreadLocal變量在當前線程中保存的值;

set() 設置ThreadLocal在當前線程的值;

remove() 用來移除當前線程中相關ThreadLocal變量;

initialValue() 是一個protected方法,一般需要重寫;

2.1 get()

源碼如下:

public T get(){

Thread t = Thread.currentThread();//獲取當前線程對象

ThreadLocalMap map = getMap(t);

if(map!=null){

//從當前線程的ThreadLocalMap獲取該thread-local variable對應的entry

ThreadLocalMap.Entry e = map.getEntry(this);

if(e!=null)

return (T)e.value;//取得目標值

}

return setInitialValue();

}

1

2

3

4

5

6

7

8

9

10

11

2.2 setIntialValue()

private T setIntialValue(){

T value = initialValue(); //默認實現(xiàn)返回null

Thread t = Thread.currentThread();//獲得當前線程;

ThreadLocalMap map = getMap(t);//得到當前線程ThreadLocalMap類型域threadLocals

if(map!=null)

map.set(this,value);//該 map 的鍵是當前 ThreadLocal 對象

else?

createMap(t,value);

return value;

}

1

2

3

4

5

6

7

8

9

10

initialValue()

? ? protected T initialValue() {

? ? ? ? return null;? ? ? ? ? ? // 默認實現(xiàn)返回 null

? ? }

1

2

3

createMap()

? ? void createMap(Thread t, T firstValue) {

? ? ? ? t.threadLocals = new ThreadLocalMap(this, firstValue); // this 指代當前 ThreadLocal 變量,為 map 的鍵??

? ? }

1

2

3

2.3 ThreadLocal類是如何為每個線程創(chuàng)建變量副本

每個線程內部有一個 ThreadLocal.ThreadLocalMap 類型的成員變量 threadLocals,這個 threadLocals 存儲了與該線程相關的所有 ThreadLocal 變量及其對應的值(”ThreadLocal 變量及其對應的值” 就是該Map中的一個 Entry)。 Key 是 ThreadLocal 變量, Value 是該 ThreadLocal 變量對應的值;

初始時,Thread里面的threadlocals為空,當ThreadLocal變量調用**get()方法或者set()**就會對Thread類中的threadlocals進行初始化,并且以當前ThreadLocal變量為鍵值,以ThreadLocal要保存的值為value,存到 threadLocals;

然后在當前線程里面,如果要使用ThreadLocal對象,就可以通過get方法獲得該線程的threadLocals,然后以該ThreadLocal對象為鍵取得其對應的 Value,也就是ThreadLocal對象中所存儲的值;

三、ThreadLocal的應用場景

Java 中,類 ThreadLocal 解決的是變量在不同線程間的隔離性。最常見的 ThreadLocal 使用場景有 數(shù)據(jù)庫連接問題、Session管理等。

3.1 數(shù)據(jù)庫連接問題

private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>() {

? ? public Connection initialValue() {

? ? ? ? return DriverManager.getConnection(DB_URL);

? ? }

};

public static Connection getConnection() {

? ? return connectionHolder.get();

}

1

2

3

4

5

6

7

8

9

3.2 Session管理

private static final ThreadLocal threadSession = new ThreadLocal();

public static Session getSession() throws InfrastructureException {

? ? Session s = (Session) threadSession.get();

? ? try {

? ? ? ? if (s == null) {

? ? ? ? ? ? s = getSessionFactory().openSession();

? ? ? ? ? ? threadSession.set(s);

? ? ? ? }

? ? } catch (HibernateException ex) {

? ? ? ? throw new InfrastructureException(ex);

? ? }

? ? return s;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

3.3 Thread-per-Request(一個請求對應一個服務器線程)

在經(jīng)典Web交互模型中,請求的處理基本上采用的都是“一個請求對應一個服務器線程”的處理方式,因此就可以將請求設置成類似ThreadLocal的形式,這樣,當某個服務器線程來處理請求時,就可以獨享該請求的處理;

四、ThreadLocal的一般使用步驟

ThreadLocal使用步驟一般分為三步:

創(chuàng)建一個ThreadLocal對象threadXxx,用來保存線程間需要隔離處理的對象xxx;

提供一個獲取要隔離訪問的數(shù)據(jù)的方法 getXxx(),在方法中判斷,若 ThreadLocal對象為null時候,應該 new() 一個隔離訪問類型的對象;

在線程類的run()方法中,通過getXxx()方法獲取要操作的數(shù)據(jù),這樣可以保證每個線程對應一個數(shù)據(jù)對象,在任何時刻都操作的是這個對象,不會交叉。

————————————————

本文題目:Java并發(fā)編程——ThreadLocal
轉載源于:http://jinyejixie.com/article32/pggopc.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供標簽優(yōu)化搜索引擎優(yōu)化、面包屑導航虛擬主機、網(wǎng)站設計公司、Google

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設
彩票| 南涧| 定远县| 博客| 巴林左旗| 黑河市| 常山县| 博客| 东兰县| 衡阳市| 东阳市| 竹北市| 长兴县| 湛江市| 屯门区| 淮安市| 张家界市| 莫力| 灌云县| 新乡县| 凤冈县| 前郭尔| 和龙市| 岑溪市| 卫辉市| 武隆县| 贵州省| 丽江市| 五华县| 琼海市| 屏南县| 鹰潭市| 辽宁省| 玛多县| 阿拉尔市| 涡阳县| 榆树市| 疏勒县| 郁南县| 奉新县| 图片|