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

ThreadLocal 与 Request 和 Session 之关联的更多相关文章

  1. 【Spring】Spring IOC原理及源码解析之scope=request、session

    一.容器 1. 容器 抛出一个议点:BeanFactory是IOC容器,而ApplicationContex则是Spring容器. 什么是容器?Collection和Container这两个单词都有存 ...

  2. struts 在Action中访问web元素(request,session等)

    出发jsp: <?xml version="1.0" encoding="GB18030" ?> <%@ page language=&quo ...

  3. Request获取Session的两种方式

    1.无请求参数 public HttpSession getSession() 获取当前request关联的session,如果当前request没有session,创建一个session. 2.有请 ...

  4. struts2在action中获取request、session、application,并传递数据

    假设仅仅是通过request.session.application传递数据,则不须要获取对应的对象也能够传递数据,代码例如以下: ScopeAction.java: package com.ithe ...

  5. Request与session与application的区别

    (1)request的setAttribute与getAttribute方法一般都是成对出现的,首先通过setAttribute方法设置属性与属性值,然后通过getAttribute方法根据属性获取到 ...

  6. web初学之request,session与application

    request (1)request的setAttribute()与getAttribute()方法一般都是成对出现,首先通过setAttribute()方法设置属性与属性值,然后通过getAttri ...

  7. strut2的拦截器之对request和session的封装

    本文主要内容是对  implements Interceptor 这种方式的探索 前提是需要了解:责任链模式 对下面这句代码的理解: Map<String, Object> session ...

  8. struts2获得request和session对象

    在struts1中,获得到系统的request或者session对象非常方便,都是按照形参传递的,但是在struts2中,request和session都被隐藏了 struts2提供两种方式访问ses ...

  9. servlet三大作用域:request,session,application

    javaweb开发中Servlet三大域对象的应用(request.session.application(ServletContext)). 1. request request是表示一个请求,只要 ...

随机推荐

  1. rpm包软件管理

    一.rpm介绍 linux服务器中所有的软件包安装方式有两种,一种是源码安装.另一种是二进制包安装(rpm)源码包安装的好处是适合不同的发行版本的linux,缺点是在编译过程中花费的时间很长,二进制包 ...

  2. NFS配置及开机自动挂载

    环境:Red Hat  6.7 服务端:192.168.163.128 客户端:192.168.163.131 背景:解决多个服务器之间数据共享 环境检查: 1.检查服务器是否安装nfs服务 rpm  ...

  3. stm32+ESP8266AT指令详细说明

    最近公司团队的项目用到ESP8266,使用的是stm32c8t6芯片,软件使用MDK,于是写下调试过程中的一些注意点.具体代码和涉及思路不能外泄,这里只给出我们调试过程中的注意的方面. 关于ESP82 ...

  4. java 的反射机制

    一:介绍 1.大纲 #1 允许程序在执行期间,调用反射API取得任何类的内部信息,并且可以直接操作任何对象的内部属性和方法. #2 学习反射,需要掌握的知识点: *实例化class类 *获取类的完整结 ...

  5. 【转】java取整和java四舍五入方法

    java取整和java四舍五入方法 import java.math.BigDecimal; import java.text.DecimalFormat; public class TestGetI ...

  6. Netty源码分析之NioEventLoop(二)—NioEventLoop的启动

    上篇文章中我们对Netty中NioEventLoop创建流程与源码进行了跟踪分析.本篇文章中我们接着分析NioEventLoop的启动流程: Netty中会在服务端启动和新连接接入时通过chooser ...

  7. JAVA 图形界面开发基础详解

    与C的win32一样,JAVA也有自己的图形界面开发,将在此篇博客中对基础部分进行讲解. 1.Java提供的图形界面类有哪些? Java提供了两套图形界面 (1)AWT组建(基础) AWT组件是jdk ...

  8. 用Thread类创建线程

    在Java中创建线程有两种方法:使用Thread类和使用Runnable接口.在使用Runnable接口时需要建立一个Thread实例.因此,无论是通过Thread类还是Runnable接口建立线程, ...

  9. U盘制作Win7安装盘的方法

    Windows 7 USB/DVD download tool 微软官方说明:http://www.microsoftstore.com/st ... Win7_usbdvd_dwnTool 下载地址 ...

  10. android 开发 命名规范

    标识符命名法标识符命名法最要有四种: 1 驼峰(Camel)命名法:又称小驼峰命名法,除首单词外,其余所有单词的第一个字母大写. 2 帕斯卡(pascal)命名法:又称大驼峰命名法,所有单词的第一个字 ...