博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ThreadLocal 在web环境下使用的边界问题
阅读量:4649 次
发布时间:2019-06-09

本文共 1561 字,大约阅读时间需要 5 分钟。

ThreadLocal 相关分析,请查看 

另外一个必须要提的点是: 
ThreadLocal在线程池环境下的使用。 
比如tomcat 提供的web http请求,一般都有线程池对请求做处理。 
这种情况下要注意,并非每次web请求时候程序运行的ThreadLocal都是唯一的,ThreadLocal的生命周期不等于一次Request的生命周期,ThreadLocal与线程对象紧密绑定的,由于Tomcat使用了线程池,线程是可能存在复用情况,这时的ThreadLocal 的使用要谨慎使用。 
web请求下 的ThreadLocal  使用要保证:请求进来的时候set,请求回去的时候remove。只有这样才能保证请求内的ThreadLocal  是唯一的。 这个特性在深刻的提醒我们:一次http请求和tomcat启动处理业务的线程并非一一对应的,而是通过一个线程池进行调度。 
错误的使用案例: 

Java代码  
  1. @Controller  
  2. public class ThreadLocalController {  
  3.     private static final ThreadLocal<Integer> id = new ThreadLocal<Integer>();  
  4.   
  5.     @ResponseBody  
  6.     @RequestMapping("/threadLocalTest")  
  7.     public Map<String, Object> threadLocalTest() {  
  8.         Integer myId = id.get();  
  9.         if (myId == null) {  
  10.             id.set(1);  
  11.         } else {  
  12.             id.set(id.get() + 1);  
  13.         }  
  14.         System.out.println(id.get());  
  15.         Map<String, Object> retMap = new LinkedHashMap<String, Object>();  
  16. retMap.put("id", id.get());  
  17.         return retMap;  
  18.     }  
  19. }  

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

Java代码  
  1. @Controller  
  2. public class ThreadLocalController {  
  3.   
  4.     private static final ThreadLocal<Integer> id = new ThreadLocal<Integer>();  
  5.   
  6.     @ResponseBody  
  7.     @RequestMapping("/threadLocalTest")  
  8.     public Map<String, Object> threadLocalTest() {  
  9.         Integer myId = id.get();  
  10.         if (myId == null) {  
  11.             id.set(1);  
  12.         } else {  
  13.             id.set(id.get() + 1);  
  14.         }  
  15.         System.out.println(id.get());  
  16.         Map<String, Object> retMap = new LinkedHashMap<String, Object>();  
  17.         retMap.put("id", id.get());  
  18.         id.remove();  
  19.         return retMap;  
  20.     }  
  21. }  

以上代码每次输出的都是1,注意id.remove() 方法的调用,在每次请求结束的时候remove对象。 
更多的情况下,做为系统级别的,可以在filter下做ThreadLocal对象set 和 remove 操作!

转载于:https://www.cnblogs.com/qiumingcheng/p/4894564.html

你可能感兴趣的文章
Monty Hall 问题与贝叶斯定理的理解
查看>>
利用JavaScript的字符串操作实现简单查字
查看>>
安全发布的模式
查看>>
python的N个小功能(更新文件)
查看>>
【bzoj 4390】 [Usaco2015 dec]Max Flow(树上差分)
查看>>
FPGA内部硬件结构简介
查看>>
前端开发面试题总结-代码篇
查看>>
javaweb学习总结(三十一)——国际化(i18n)
查看>>
23种设计模式[1]:单例模式
查看>>
好的学习材料
查看>>
【DRF分页】
查看>>
6.1 文件对象常用方法与属性
查看>>
排列组合问题
查看>>
小知识点
查看>>
【笔记】HybridApp中使用Promise化的JS-Bridge
查看>>
模拟赛 sutoringu
查看>>
hdu 1253 胜利大逃亡 (广搜)
查看>>
华为上机试---购物单(算法:背包问题)
查看>>
PHP操作Mongodb API 及使用类 封装好的MongoDB操作类
查看>>
PHP实现经典算法
查看>>