日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java 线程变量put_Java线程(篇外篇):线程本地变量ThreadLocal

發(fā)布時間:2024/7/19 java 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 线程变量put_Java线程(篇外篇):线程本地变量ThreadLocal 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

首先說明ThreadLocal存放的值是線程內共享的,線程間互斥的,主要用于線程內共享一些數(shù)據(jù),避免通過參數(shù)來傳遞,這樣處理后,能夠優(yōu)雅的解決一些實際問題,比如hibernate中的OpenSessionInView,就是使用ThreadLocal保存Session對象,還有我們經常用ThreadLocal存放Connection,代碼如:

/**

*?數(shù)據(jù)庫連接管理類

*?@author?爽

*

*/

public?class?ConnectionManager?{

/**?線程內共享Connection,ThreadLocal通常是全局的,支持泛型?*/

private?static?ThreadLocal?threadLocal?=?new?ThreadLocal();

public?static?Connection?getCurrConnection()?{

//?獲取當前線程內共享的Connection

Connection?conn?=?threadLocal.get();

try?{

//?判斷連接是否可用

if(conn?==?null?||?conn.isClosed())?{

//?創(chuàng)建新的Connection賦值給conn(略)

//?保存Connection

threadLocal.set(conn);

}

}?catch?(SQLException?e)?{

//?異常處理

}

return?conn;

}

/**

*?關閉當前數(shù)據(jù)庫連接

*/

public?static?void?close()?{

//?獲取當前線程內共享的Connection

Connection?conn?=?threadLocal.get();

try?{

//?判斷是否已經關閉

if(conn?!=?null?&&?!conn.isClosed())?{

//?關閉資源

conn.close();

//?移除Connection

threadLocal.remove();

conn?=?null;

}

}?catch?(SQLException?e)?{

//?異常處理

}

}

}

這樣處理的好處:

統(tǒng)一管理Connection;

不需要顯示傳參Connection,代碼更優(yōu)雅;

降低耦合性。

ThreadLocal有四個方法,分別為:

initialValue

protected T initialValue()

返回此線程局部變量的當前線程的初始值。最多在每次訪問線程來獲得每個線程局部變量時調用此方法一次,即線程第一次使用 get() 方法訪問變量的時候。如果線程先于 get 方法調用 set(T) 方法,則不會在線程中再調用 initialValue 方法。

該實現(xiàn)只返回 null;如果程序員希望將線程局部變量初始化為 null 以外的某個值,則必須為 ThreadLocal 創(chuàng)建子類,并重寫此方法。通常,將使用匿名內部類。initialValue 的典型實現(xiàn)將調用一個適當?shù)臉嬙旆椒?#xff0c;并返回新構造的對象。返回:返回此線程局部變量的初始值

get

public T get()

返回此線程局部變量的當前線程副本中的值。如果這是線程第一次調用該方法,則創(chuàng)建并初始化此副本。返回:此線程局部變量的當前線程的值

set

public void set(T?value)

將此線程局部變量的當前線程副本中的值設置為指定值。許多應用程序不需要這項功能,它們只依賴于 initialValue() 方法來設置線程局部變量的值。參數(shù):value - 存儲在此線程局部變量的當前線程副本中的值。

remove

public void remove()

移除此線程局部變量的值。這可能有助于減少線程局部變量的存儲需求。如果再次訪問此線程局部變量,那么在默認情況下它將擁有其 initialValue。

很多人對ThreadLocal存在一定的誤解,說ThreadLocal中有一個全局的Map,set時執(zhí)行map.put(Thread.currentThread(), value),get和remove時也同理,但SUN的大師們是否是如此實現(xiàn)的,我們只能去看源碼了。

set方法:

/**

*?Sets?the?current?thread's?copy?of?this?thread-local?variable

*?to?the?specified?value.??Most?subclasses?will?have?no?need?to

*?override?this?method,?relying?solely?on?the?{@link?#initialValue}

*?method?to?set?the?values?of?thread-locals.

*

*?@param?value?the?value?to?be?stored?in?the?current?thread's?copy?of

*????????this?thread-local.

*/

public?void?set(T?value)?{

//?獲取當前線程對象

Thread?t?=?Thread.currentThread();

//?獲取當前線程本地變量Map

ThreadLocalMap?map?=?getMap(t);

//?map不為空

if?(map?!=?null)

//?存值

map.set(this,?value);

else

//?創(chuàng)建一個當前線程本地變量Map

createMap(t,?value);

}

/**

*?Get?the?map?associated?with?a?ThreadLocal.?Overridden?in

*?InheritableThreadLocal.

*

*?@param??t?the?current?thread

*?@return?the?map

*/

ThreadLocalMap?getMap(Thread?t)?{

//?獲取當前線程的本地變量Map

return?t.threadLocals;

}

這里注意,ThreadLocal中是有一個Map,但這個Map不是我們平時使用的Map,而是ThreadLocalMap,ThreadLocalMap是ThreadLocal的一個內部類,不對外使用的。當使用ThreadLocal存值時,首先是獲取到當前線程對象,然后獲取到當前線程本地變量Map,最后將當前使用的ThreadLocal和傳入的值放到Map中,也就是說ThreadLocalMap中存的值是[ThreadLocal對象, 存放的值],這樣做的好處是,每個線程都對應一個本地變量的Map,所以一個線程可以存在多個線程本地變量。

get方法:

/**

*?Returns?the?value?in?the?current?thread's?copy?of?this

*?thread-local?variable.??If?the?variable?has?no?value?for?the

*?current?thread,?it?is?first?initialized?to?the?value?returned

*?by?an?invocation?of?the?{@link?#initialValue}?method.

*

*?@return?the?current?thread's?value?of?this?thread-local

*/

public?T?get()?{

Thread?t?=?Thread.currentThread();

ThreadLocalMap?map?=?getMap(t);

if?(map?!=?null)?{

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

if?(e?!=?null)

return?(T)e.value;

}

//?如果值為空,則返回初始值

return?setInitialValue();

}? ? ? ?有了之前set方法的分析,get方法也同理,需要說明的是,如果沒有進行過set操作,那從ThreadLocalMap中拿到的值就是null,這時get方法會返回初始值,也就是調用initialValue()方法,ThreadLocal中這個方法默認返回null。當我們有需要第一次get時就能得到一個值時,可以繼承ThreadLocal,并且覆蓋initialValue()方法。

(完)

總結

以上是生活随笔為你收集整理的java 线程变量put_Java线程(篇外篇):线程本地变量ThreadLocal的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。