ThreadLocal<T> 類行是 .NET Framework 4.0 才開始支援的類型,MSDN 的解釋隻有簡單的一句話:提供資料的線程本地存儲,其提供的執行個體代碼也不太好,有點為了示範而示範的目的。是以,一眼望去,我們并不知道這個類型有什麼用。
一:ThreadLocal 在 JAVA 中的應用
其實這個類型在 JAVA 中早就存在了,并且在 JAVA 的體系中的應用也被廣泛提到,現在我們把這些概念用 .NET 來描述一遍。
先看段 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應用伺服器 關于對于 Request 和 Thread 的處理:
一次請求會産生一個 Thread 嗎?不會,WEB引擎(如ASP.NET 引擎)會維護一個托管線程池,多次請求間可能會用到一個線程(PS:嚴格意義上來說,是異步,不是線程,但包裝成托管線程的模樣)。
接着繼續說代碼:首先判斷目前線程中有沒有放進去 session ,如果還沒有,那麼通過 sessionFactory().openSession() 來建立一個 session ,再将 session set 到線程中,實際是放到目前線程的 ThreadLocal 對象上。要注意的是,其他線程中是取不到這個 session 的。
二:ThreadLocal 在 .NET 中的表現
首先,兩個類型在 API 聲明上是不一緻的,但是目的都是一樣的:
讓各個線程維持自己的變量。
現在,寫一段代碼測試下:
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=0 Thread.CurrentThread.ManagedThreadId=9 sampLocal=57902434
不停滴重新整理,如果 threadid 為 9 ,則得到的 sampLocal 是同一個對象。
三:ThreadLocal 與 static
可以了解為
1:ThreadLocal 是線程内的 static 變量,也許其名字命名為 ThreadStatic 更好?
2:static 是全部線程都可共用的變量。
四:ThreadLocal 的用處
那麼,這段代碼為什麼要這麼設計,也許基于一點:
避免參數傳遞的通路方式,但是要注意get()到的是那同一個共享對象,并發通路問題要靠其他手段來解決;
本文轉自最課程陸敏技部落格園部落格,原文連結:http://www.cnblogs.com/luminji/p/3769719.html,如需轉載請自行聯系原作者