程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> ThreadLocal 與 Request 和 Session 之關聯

ThreadLocal 與 Request 和 Session 之關聯

編輯:C#入門知識

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()到的是那同一個共享對象,並發訪問問題要靠其他手段來解決;

 

參考:ThreadLocal

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved