`

ThreadLocal 在web环境下使用的边界问题

阅读更多
ThreadLocal 相关分析,请查看http://wangxinchun.iteye.com/blog/1884228
另外一个必须要提的点是:
ThreadLocal在线程池环境下的使用。
比如tomcat 提供的web http请求,一般都有线程池对请求做处理。

这种情况下要注意,并非每次web请求时候程序运行的ThreadLocal都是唯一的,ThreadLocal的生命周期不等于一次Request的生命周期,ThreadLocal与线程对象紧密绑定的,由于Tomcat使用了线程池,线程是可能存在复用情况,这时的ThreadLocal 的使用要谨慎使用。

web请求下 的ThreadLocal  使用要保证:请求进来的时候set,请求回去的时候remove。只有这样才能保证请求内的ThreadLocal  是唯一的。 这个特性在深刻的提醒我们:一次http请求和tomcat启动处理业务的线程并非一一对应的,而是通过一个线程池进行调度。
错误的使用案例:
@Controller
public class ThreadLocalController {
	private static final ThreadLocal<Integer> id = new ThreadLocal<Integer>();

	@ResponseBody
	@RequestMapping("/threadLocalTest")
	public Map<String, Object> threadLocalTest() {
		Integer myId = id.get();
		if (myId == null) {
			id.set(1);
		} else {
			id.set(id.get() + 1);
		}
		System.out.println(id.get());
		Map<String, Object> retMap = new LinkedHashMap<String, Object>();
retMap.put("id", id.get());
		return retMap;
	}
}

以上代码运行的时候会发现,命令行打印的id 是不确定的,这时因为tomcat本身对请求做线程池缓存业务处理线程导致的。

正确的使用案例:
@Controller
public class ThreadLocalController {

	private static final ThreadLocal<Integer> id = new ThreadLocal<Integer>();

	@ResponseBody
	@RequestMapping("/threadLocalTest")
	public Map<String, Object> threadLocalTest() {
		Integer myId = id.get();
		if (myId == null) {
			id.set(1);
		} else {
			id.set(id.get() + 1);
		}
		System.out.println(id.get());
		Map<String, Object> retMap = new LinkedHashMap<String, Object>();
		retMap.put("id", id.get());
		id.remove();
		return retMap;
	}
}

以上代码每次输出的都是1,注意id.remove() 方法的调用,在每次请求结束的时候remove对象。

更多的情况下,做为系统级别的,可以在filter下做ThreadLocal对象set 和 remove 操作!
1
0
分享到:
评论
6 楼 王新春 2014-07-30  
root123 写道
王新春 写道
thc1987 写道
我现在的做法是做个过滤器,每次请求都更新一下

恩,可以根据实际的情况,对web请求型的做成filter 不错。但是在定时任务或者线程池中,只要注意 set remove 成对出现即可。

每次任务开始时,都进行设置。这样的方案可行吗?

当然也可以。
5 楼 root123 2014-07-30  
王新春 写道
thc1987 写道
我现在的做法是做个过滤器,每次请求都更新一下

恩,可以根据实际的情况,对web请求型的做成filter 不错。但是在定时任务或者线程池中,只要注意 set remove 成对出现即可。

每次任务开始时,都进行设置。这样的方案可行吗?
4 楼 王新春 2014-06-13  
thc1987 写道
我现在的做法是做个过滤器,每次请求都更新一下

恩,可以根据实际的情况,对web请求型的做成filter 不错。但是在定时任务或者线程池中,只要注意 set remove 成对出现即可。
3 楼 thc1987 2014-06-13  
我现在的做法是做个过滤器,每次请求都更新一下
2 楼 王新春 2014-06-12  
kidding87 写道
感觉你把Threadlocal用错场景了,而且需要是的request.get/setAttribute

我仅仅是做ThreadLocal 的功能和使用场景的演示的
1 楼 kidding87 2014-06-12  
感觉你把Threadlocal用错场景了,而且需要是的request.get/setAttribute

相关推荐

    ThreadLocal和事务

    在Web应用中,尤其是在多线程环境中,ThreadLocal常用于存储线程相关的数据,如数据库连接。使用ThreadLocal来管理数据库连接,可以确保每个请求的生命周期内,连接只被该请求使用,避免了线程间的数据共享问题,...

    Hibernager_Session_Manager_ThreadLocal

    8. **缺点与注意事项**:ThreadLocal使用不当可能导致内存泄漏,尤其是在Web应用中,需要确保在Web请求结束时清理ThreadLocal。此外,过多的ThreadLocal变量也可能增加内存消耗。 总结起来,"Hibernage_Session_...

    hibernate中session的管理

    在传统的多线程Servlet环境下,如果将Session作为类变量存储,如上述例子中的`TestServlet`,则会面临线程安全问题。由于Servlet容器(如Tomcat)通常只创建一个Servlet实例供所有请求共享,每个线程在执行时可能会...

    hibernate的事务核并发

    在多线程环境中,如Web应用或EJB容器,为了保证`Session`的线程安全和资源的有效利用,可以使用`ThreadLocal`变量来存储当前线程的`Session`实例。然而,在CMT环境中,由于单个session bean可能会被多个线程并行调用...

    day36 11-Hibernate中的事务:当前线程中的session

    在Web应用中,通常使用Servlet容器如Tomcat,它支持ThreadLocal机制,能够为每个请求创建并维护一个独立的Session对象。这种方式称为“ThreadLocal Session”。 使用ThreadLocal Session的一个关键好处是事务的自动...

    Java面试框架高频问题2019

    - 为了确保在嵌套事务中正确处理事务边界,避免出现脏读等问题。 **问题十四:介绍一下Spring的事物管理** - **编程式事务管理**:通过编程的方式控制事务的开始、提交或回滚。 - **声明式事务管理**:通过配置...

    J2EE开发全程实录(JAVA项目开发)

    这部分讲述了多账套的实现,线程变量管理(使用ThreadLocal),事务管理,如事务的边界、隔离级别和Spring的声明型事务。还讨论了会话服务的生命周期管理以及IValueObject接口,为数据访问提供基础支持。 【层间...

    SpringBoot整合Mybatis连接SQL Server 双数据源配置

    在这种情况下,"SpringBoot整合Mybatis连接SQL Server 双数据源配置" 是一个常见的技术实践。Spring Boot以其简洁的配置和强大的自动化配置能力,使得集成Mybatis并管理多个数据源变得相对简单。下面我们将详细介绍...

    J2EE开发全程实录PDF J2EE开发全程实录PDF

    - **安全问题**:探讨了在分布式环境下保障数据安全的方法和技术。 #### 元数据引擎 - **MDA概述**:模型驱动架构(Model Driven Architecture)是一种软件工程方法论,强调使用模型作为设计和实现的基础。 - **...

    百度持续交付项目组面试题

    **ThreadLocal**类提供了线程局部变量,这些变量在线程之间是独立的,每个线程都有自己的副本,因此不会发生线程安全问题。 #### 数据库 ##### 关系型数据库 **MySQL查询联接方式**包括内联接(INNER JOIN)、左...

    1剑盛二面准备试题.txt1剑盛二面准备试题.txt

    51. **ThreadLocal的使用场景**:可以用来在多线程中存储每个线程自己的局部变量。 52. **synchronized底层实现原理**:当synchronized修饰方法时,通过monitorenter和monitorexit指令实现同步。当修饰代码块时,会...

    bnpprhinos:交响黑客马拉松

    【bnpprhinos:交响黑客马拉松】是一个聚焦于Java技术的创新活动,旨在集结开发者、创新者和音乐爱好者,通过编程与音乐的融合,挑战技术的边界,探索新的可能性。这个项目可能涉及到多领域的交叉合作,将编程的严谨...

Global site tag (gtag.js) - Google Analytics