当前位置: 首页 > news >正文

做网站外包的公司好干嘛网站子页怎么做 视频

做网站外包的公司好干嘛,网站子页怎么做 视频,为什么手机进网站乱码,东莞营销推广在生产上遇到一个诡异的问题#xff0c;有时获取到的用户信息是别人的。查看代码后#xff0c;我发现他使用了 ThreadLocal 来缓存获取到的用户信息。 我们知道#xff0c;ThreadLocal 适用于变量在线程间隔离#xff0c;而在方法或类间共享的场景。如果用户信息的获取比较…在生产上遇到一个诡异的问题有时获取到的用户信息是别人的。查看代码后我发现他使用了 ThreadLocal 来缓存获取到的用户信息。 我们知道ThreadLocal 适用于变量在线程间隔离而在方法或类间共享的场景。如果用户信息的获取比较昂贵比如从数据库查询用户信息那么在 ThreadLocal 中缓存数据是比较合适的做法。但这么做为什么会出现用户信息错乱的 Bug 呢 我们看一个具体的案例吧。 使用 Spring Boot 创建一个 Web 应用程序使用 ThreadLocal 存放一个 Integer 的值来暂且代表需要在线程中保存的用户信息这个值初始是 null。在业务逻辑中我先从 ThreadLocal 获取一次值然后把外部传入的参数设置到 ThreadLocal 中来模拟从当前上下文获取到用户信息的逻辑随后再获取一次值最后输出两次获得的值和线程名称。 private static final ThreadLocalInteger currentUser ThreadLocal.withInitial(() - null);GetMapping(wrong) public Map wrong(RequestParam(userId) Integer userId) {//设置用户信息之前先查询一次ThreadLocal中的用户信息String before Thread.currentThread().getName() : currentUser.get();//设置用户信息到ThreadLocalcurrentUser.set(userId);//设置用户信息之后再查询一次ThreadLocal中的用户信息String after Thread.currentThread().getName() : currentUser.get();//汇总输出两次查询结果Map result new HashMap();result.put(before, before);result.put(after, after);return result; }按理说在设置用户信息之前第一次获取的值始终应该是 null但我们要意识到程序运行在 Tomcat 中执行程序的线程是 Tomcat 的工作线程而 Tomcat 的工作线程是基于线程池的。 顾名思义线程池会重用固定的几个线程一旦线程重用那么很可能首次从 ThreadLocal 获取的值是之前其他用户的请求遗留的值。这时ThreadLocal 中的用户信息就是其他用户的信息。 为了更快地重现这个问题我在配置文件中设置一下 Tomcat 的参数把工作线程池最大线程数设置为 1这样始终是同一个线程在处理请求 server.tomcat.max-threads1 运行程序后先让用户 1 来请求接口可以看到第一和第二次获取到用户 ID 分别是 null 和 1符合预期 随后用户 2 来请求接口这次就出现了 Bug第一和第二次获取到用户 ID 分别是 1 和 2显然第一次获取到了用户 1 的信息原因就是 Tomcat 的线程池重用了线程。从图中可以看到两次请求的线程都是同一个线程http-nio-8080-exec-1。 这个例子告诉我们在写业务代码时首先要理解代码会跑在什么线程上 我们可能会抱怨学多线程没用因为代码里没有开启使用多线程。但其实可能只是我们没有意识到在 Tomcat 这种 Web 服务器下跑的业务代码本来就运行在一个多线程环境否则接口也不可能支持这么高的并发并不能认为没有显式开启多线程就不会有线程安全问题。 因为线程的创建比较昂贵所以 Web 服务器往往会使用线程池来处理请求这就意味着线程会被重用。这时使用类似 ThreadLocal 工具来存放一些数据时需要特别注意在代码运行完后显式地去清空设置的数据。如果在代码中使用了自定义的线程池也同样会遇到这个问题。 理解了这个知识点后我们修正这段代码的方案是在代码的 finally 代码块中显式清除 ThreadLocal 中的数据。这样一来新的请求过来即使使用了之前的线程也不会获取到错误的用户信息了。修正后的代码如下 GetMapping(right) public Map right(RequestParam(userId) Integer userId) {String before Thread.currentThread().getName() : currentUser.get();currentUser.set(userId);try {String after Thread.currentThread().getName() : currentUser.get();Map result new HashMap();result.put(before, before);result.put(after, after);return result;} finally {//在finally代码块中删除ThreadLocal中的数据确保数据不串currentUser.remove();} } 重新运行程序可以验证再也不会出现第一次查询用户信息查询到之前用户请求的 Bug 总结:  使用 ThreadLocal 来缓存数据以为 ThreadLocal 在线程之间做了隔离不会有线程安全问题没想到线程重用导致数据串了。请务必记得在业务逻辑结束之前清理 ThreadLocal 中的数据。
http://www.zqtcl.cn/news/835838/

相关文章:

  • 泸州高端网站建设公司上海企业网站
  • wordpress 建站 知乎济南全包圆装修400电话
  • 织梦建设两个网站 视频影视公司宣传片
  • 北京小企业网站建设那个做网站好
  • 怎样用模块做网站深圳网站建设制作厂家
  • 网站项目中的工作流程网站建设社区
  • 建设厅网站查询电工证件提供网站建设公司哪家好
  • 免费网站软件下载安装称多网站建设
  • 网站客户续费深圳福田地图
  • 连云港做电商网站的公司营销公司网站模板
  • 沈阳企业网站优化排名方案富阳做网站公司
  • 企业网站优化报价自己做个网站怎么赚钱
  • 做ui的网站有哪些网站建设订单模板
  • 重庆企业网站优化wordpress 接收询盘
  • 小米4路由器可以做网站嘛杭州淘宝代运营公司十大排名
  • 枞阳做网站的百度搜索入口
  • 网站建设提议徐州网站建设方案咨询
  • 昆明高端网站建设专门做游轮的网站
  • 教育培训网站抄袭网站是广西住房和城乡建设厅
  • 广州做网站建设的公司哪家好网站建设运营公司
  • 网站集约化建设 技术国内永久在线免费建站
  • 极简资讯网站开发有什么免费推广项目的好软件
  • 网站有哪几种类型如何让百度分享按钮在网站每个页面都有
  • 北京市昌平建设工程招标网站网站建设要学哪些软件有哪些方面
  • 部队内网网站建设方案诱导视频网站怎么做
  • 安徽省美好乡村建设网站郑州网站建设 论坛
  • 手机网站怎么建设软件外包公司绩效考核内容
  • 北京最大的火车站网站免费推广方式
  • 外贸网站建设系统工程公司名称大全
  • 手机视频网站建站吴江区经济开发区建设工程网站