真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

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

ThreadLocal

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

概述

一、對(duì)ThreadLocal的理解

1.1 ThreadLocal在JDK中的定義

1.2 應(yīng)用場景

二、深入分析ThreaLocal類

2.1 get()

2.2 setIntialValue()

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

三、ThreadLocal的應(yīng)用場景

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

3.2 Session管理

3.3 Thread-per-Request(一個(gè)請(qǐng)求對(duì)應(yīng)一個(gè)服務(wù)器線程)

四、ThreadLocal的一般使用步驟

概述

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

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

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

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

一、對(duì)ThreadLocal的理解

1.1 ThreadLocal在JDK中的定義

每個(gè)線程都有關(guān)于該 ThreadLocal變量 的私有值 ,并且對(duì)其他線程是不可見的;

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

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

1.2 應(yīng)用場景

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

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

二、深入分析ThreaLocal類

ThreadLocal中,一共提供了四個(gè)方法:

public T get() { }

public void set(T value){ }

public void remove(){ }

protected T initialValue{ }

1

2

3

4

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

set() 設(shè)置ThreadLocal在當(dāng)前線程的值;

remove() 用來移除當(dāng)前線程中相關(guān)ThreadLocal變量;

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

2.1 get()

源碼如下:

public T get(){

Thread t = Thread.currentThread();//獲取當(dāng)前線程對(duì)象

ThreadLocalMap map = getMap(t);

if(map!=null){

//從當(dāng)前線程的ThreadLocalMap獲取該thread-local variable對(duì)應(yīng)的entry

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

if(e!=null)

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

}

return setInitialValue();

}

1

2

3

4

5

6

7

8

9

10

11

2.2 setIntialValue()

private T setIntialValue(){

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

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

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

if(map!=null)

map.set(this,value);//該 map 的鍵是當(dāng)前 ThreadLocal 對(duì)象

else?

createMap(t,value);

return value;

}

1

2

3

4

5

6

7

8

9

10

initialValue()

? ? protected T initialValue() {

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

? ? }

1

2

3

createMap()

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

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

? ? }

1

2

3

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

每個(gè)線程內(nèi)部有一個(gè) ThreadLocal.ThreadLocalMap 類型的成員變量 threadLocals,這個(gè) threadLocals 存儲(chǔ)了與該線程相關(guān)的所有 ThreadLocal 變量及其對(duì)應(yīng)的值(”ThreadLocal 變量及其對(duì)應(yīng)的值” 就是該Map中的一個(gè) Entry)。 Key 是 ThreadLocal 變量, Value 是該 ThreadLocal 變量對(duì)應(yīng)的值;

初始時(shí),Thread里面的threadlocals為空,當(dāng)ThreadLocal變量調(diào)用**get()方法或者set()**就會(huì)對(duì)Thread類中的threadlocals進(jìn)行初始化,并且以當(dāng)前ThreadLocal變量為鍵值,以ThreadLocal要保存的值為value,存到 threadLocals;

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

三、ThreadLocal的應(yīng)用場景

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

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

private static ThreadLocal connectionHolder = new ThreadLocal() {

? ? 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(一個(gè)請(qǐng)求對(duì)應(yīng)一個(gè)服務(wù)器線程)

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

四、ThreadLocal的一般使用步驟

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

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

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

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

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


文章名稱:Java并發(fā)編程——ThreadLocal
當(dāng)前地址:http://weahome.cn/article/pggopc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部