ThreadLocal<T> 類(lèi)行是 .NET Framework 4.0 才開(kāi)始支持的類(lèi)型,MSDN 的解釋只有簡(jiǎn)單的一句話(huà):提供數(shù)據(jù)的線(xiàn)程本地存儲(chǔ),其提供的實(shí)例代碼也不太好,有點(diǎn)為了演示而演示的目的。所以,一眼望去,我們并不知道這個(gè)類(lèi)型有什么用。
一:ThreadLocal 在 java 中的應(yīng)用
其實(shí)這個(gè)類(lèi)型在 JAVA 中早就存在了,并且在 JAVA 的體系中的應(yīng)用也被廣泛提到,現(xiàn)在我們把這些概念用 .NET 來(lái)描述一遍。
先看段 JAVA 代碼,這端代碼存在于 Hibernate 中:
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; }
要看懂或者明白這段代碼的意義,我們需要了解一般 WEB應(yīng)用服務(wù)器 關(guān)于對(duì)于 Request 和 Thread 的處理:
一次請(qǐng)求會(huì)產(chǎn)生一個(gè) Thread 嗎?不會(huì),WEB引擎(如asp.net 引擎)會(huì)維護(hù)一個(gè)托管線(xiàn)程池,多次請(qǐng)求間可能會(huì)用到一個(gè)線(xiàn)程(PS:嚴(yán)格意義上來(lái)說(shuō),是異步,不是線(xiàn)程,但包裝成托管線(xiàn)程的模樣)。
接著繼續(xù)說(shuō)代碼:首先判斷當(dāng)前線(xiàn)程中有沒(méi)有放進(jìn)去 session ,如果還沒(méi)有,那么通過(guò) sessionFactory().openSession() 來(lái)創(chuàng)建一個(gè) session ,再將 session set 到線(xiàn)程中,實(shí)際是放到當(dāng)前線(xiàn)程的 ThreadLocal 對(duì)象上。要注意的是,其他線(xiàn)程中是取不到這個(gè) session 的。
二:ThreadLocal 在 .NET 中的表現(xiàn)
首先,兩個(gè)類(lèi)型在 API 聲明上是不一致的,但是目的都是一樣的:
讓各個(gè)線(xiàn)程維持自己的變量。
現(xiàn)在,寫(xiě)一段代碼測(cè)試下:
public partial class Handler : System.Web.UI.Page{ private static ThreadLocal<Sample> sampLocal = new ThreadLocal<Sample>(); protected void Page_Load(object sender, EventArgs e) { if (!sampLocal.IsValueCreated) { sampLocal.Value = new Sample(); } Response.Write("Thread.CurrentContext.ContextID=" + Thread.CurrentContext.ContextID + "<br/>"); Response.Write("Thread.CurrentThread.ManagedThreadId=" + Thread.CurrentThread.ManagedThreadId + "<br/>"); Response.Write("sampLocal=" + sampLocal.Value.GetHashCode() + "<br/>"); }}
public class Sample{}
其最有可能的輸出是:
Thread.CurrentContext.ContextID=0Thread.CurrentThread.ManagedThreadId=9sampLocal=57902434
不停滴刷新,如果 threadid 為 9 ,則得到的 sampLocal 是同一個(gè)對(duì)象。
三:ThreadLocal 與 static
可以理解為
1:ThreadLocal 是線(xiàn)程內(nèi)的 static 變量,也許其名字命名為 ThreadStatic 更好?
2:static 是全部線(xiàn)程都可共用的變量。
四:ThreadLocal 的用處
那么,這段代碼為什么要這么設(shè)計(jì),也許基于一點(diǎn):
避免參數(shù)傳遞的訪(fǎng)問(wèn)方式,但是要注意get()到的是那同一個(gè)共享對(duì)象,并發(fā)訪(fǎng)問(wèn)問(wèn)題要靠其他手段來(lái)解決;
參考:ThreadLocal
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注