Spring中采用公共变量并发问题解决
由于系统采用springmvc框架,springmvc核心控制器DispatcherServlet 默认为每个controller生成单一实例来处理所有用户请求,所以在这个单一实例的controller中,它的XXXService也是一个实例处理所有请求, 这样XXXService的成员变量就被所有请求共享。这样就会出现并发请求时变量内容被篡改的问题。
那么出现这种问题如何解决呢?
第一种方式: 既然是全局变量惹的祸,那就将全局变量都编程局部变量,通过方法参数来传递,但是如果多个方法都需要该参数的话,传参就相当繁琐。
第二种方式: jdk提供了java.lang.ThreadLocal,它为多线程并发提供了新思路。 (当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本)
ThreadLocal类用来提供线程内部的局部变量。这些变量在多线程环境下访问(通过get或set方法访问)时能保证各个线程里的变量相对独立于其他线程内的变量,ThreadLocal实例通常来说都是private static类型。
总结:ThreadLocal不是为了解决多线程访问共享变量,而是为每个线程创建一个单独的变量副本,提供了保持对象的方法和避免参数传递的复杂性。
父类ThreadLocal定义:
//存储MessageContentModel对象,防止对象并发覆盖private ThreadLocal<MessageContentModel> msgContentModelTL = new ThreadLocal<MessageContentModel>();//存储HandlerContext对象,防止对象并发覆盖private ThreadLocal<HandlerContext> contextModelTL = new ThreadLocal<HandlerContext>();
父类设置对象值:
/*** 日志对象*/public HandlerContext getContext() {return contextModelTL.get() != null ? contextModelTL.get() : new HandlerContext();}private void setContext(HandlerContext context) {contextModelTL.set(context);}/*** 消息内容服务公用模型*/public MessageContentModel getMsgContentModel() {return msgContentModelTL.get() != null ? msgContentModelTL.get() : new MessageContentModel();}private void setMsgContentModel(MessageContentModel msgContentModel) {msgContentModelTL.set(msgContentModel);}
子类使用:
this.getContext().writeLogTag("获取链接失败");
ThreadLocal的主要应用场景为按线程多实例(每个线程对应一个实例)的对象的访问,并且这个对象很多地方都要用到。例如:同一个网站登录用户,每个用户服务器会为其开一个线程,每个线程中创建一个ThreadLocal,里面存用户基本信息等,在很多页面跳转时,会显示用户信息或者得到用户的一些信息等频繁操作,这样多线程之间并没有联系而且当前线程也可以及时获取想要的数据。
实现原理:
ThreadLocal可以看做是一个容器,容器里面存放着属于当前线程的变量。ThreadLocal类提供了四个对外开放的接口方法,这也是用户操作ThreadLocal类的基本方法:
(1) void set(Object value)设置当前线程的线程局部变量的值。
(2) public Object get()该方法返回当前线程所对应的线程局部变量。
(3) public void remove()将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。
(4) protected Object initialValue()返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次,ThreadLocal中的缺省实现直接返回一个null。
可以通过上述的几个方法实现ThreadLocal中变量的访问,数据设置,初始化以及删除局部变量,那ThreadLocal内部是如何为每一个线程维护变量副本的呢?
其实在ThreadLocal类中有一个静态内部类ThreadLocalMap(其类似于Map),用键值对的形式存储每一个线程的变量副本,ThreadLocalMap中元素的key为当前ThreadLocal对象,而value对应线程的变量副本,每个线程可能存在多个ThreadLocal。
http://blog.csdn.net/lhqj1992/article/details/52451136
Spring中采用公共变量并发问题解决相关推荐
- python公共变量_Python中的公共变量
python公共变量 By default all numbers, methods, variables of the class are public in the Python programm ...
- laravel 向模板中添加公共变量
1.在App\Providers\AppServiceProvider 添加 view()->composer('*', //模板名多个可用数组"['blade1', 'blade2' ...
- 在Spring中采用声明式方法对Hibernate和JDBC进行统一的事务配置(AOP)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- access全局变量_在MS Access中使用“全局”变量
access全局变量 As developers, we frequently need to store values for use throughout our application or t ...
- RobotFramework 之 公共变量
RobotFramework 之 公共变量 公共变量 RF公共变量的使用 list变量 dict变量 使用变量文件 公共变量 前面了解了通过资源文件对用户关键字进行管理,将重复的内容提取出来,简化测试 ...
- Spring中的Bean默认是单例还是多例?如何保证并发安全?
点击关注公众号,实用技术文章及时了解 Spring的bean默认都是单例的,某些情况下,单例是并发不安全的,以Controller举例,问题根源在于,我们可能会在Controller中定义成员变量,如 ...
- 系统中异常公共处理模块 in spring boot
最近在用spring boot 做微服务,所以对于异常信息的 [友好展示]有要求,我设计了两点: 一. 在业务逻辑代码中,异常的抛出 我做了限定,一般只会是三种: 1. OmcException // ...
- 解析docker中的环境变量使用和常见问题解决
解析docker中的环境变量使用和常见问题解决 参考文章: (1)解析docker中的环境变量使用和常见问题解决 (2)https://www.cnblogs.com/xuxinkun/p/10531 ...
- 常见设计模式实现、详解及在Spring中的应用
Spring中涉及到的设计模式详解 一.单例模式 1.介绍 要点: 某个类只能有一个实例: 它必须自行创建这个实例: 它必须自行向整个系统提供这个实例. 实现: 单例模式的类只提供私有的构造函数(这样 ...
最新文章
- wpf+xml实现的一个随机生成早晚餐的小demo
- mapgis矢量化怎么打分数_mapgis矢量化的详细工作流程
- 监听者模式理解(Swing)
- java多线程runnable_Java 多线程 之 Runnable
- java中换行符号_Java中的回车换行符/n /r /t分析
- stm32超声波测距代码_干货!特斯拉Autopilot核心传感器解读超声波雷达篇
- 索引原理及几种索引类型区别
- 致敬各位10年阿里的前端开发
- 简单的Java服务器和客户端的通信
- (7)Spring框架----面向切面编程(一个简单的约定游戏)
- aforge java_C#使用Aforge调用摄像头拍照的方法
- IINA+ :在IINA播放器上观看直播
- Java基础-SSM之Spring的AOP编程
- linux 内核参数 pte,Linux下通过线性地址得到页表项pte(X86和龙芯2F下)
- 思维破局:认知水平低,是一个人最致命的短板
- Tracking 1.3 Online Trackers
- 有监督学习、无监督学习、半监督学习、强化学习
- 基于FPGA的图像处理之幂律(伽马校正)变化
- 2023前端大厂面试题之JavaScript篇(4)
- 【VUE】将图片的url或file类型转换成base64,并压缩图片大小