多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## 一、概述 Spring中的Bean默认是单例模式的,默认情况下@Controller没有加上@Scope,没有加@Scope就是默认值singleton,单例的,意思就是系统只会初始化一次Controller容器,所以每次请求的都是同一个Controller容器,当然是非线程安全的。对于无状态Bean来说,他们都是线程安全的,但对于有状态的bean来说,则存在线程安全的问题; ## 二、方案 ### **简单方案** 如果Bean是有状态的 那就需要开发人员自己来进行线程安全的保证,最简单的办法就是改变bean的作用域 把`singleton`改为`protopyte`这样每次请求Bean就相当于是 new Bean() 这样就可以保证线程的安全了; 实例: ![](https://img.kancloud.cn/54/6c/546cefd12916d567be7d657fe46ccdb6_1838x892.png) ![](https://img.kancloud.cn/63/38/63383a911be254e5316460d2e0b19330_1846x892.png) 效果: 原版本,高并发情况下,会出现数据错乱; 经过调整后,问题得到解决; ### **ThreadLocal** 1) 常量始终是线程安全的,因为只存在读操作; 2)局部变量是线程安全的。因为每执行一个方法,都会在独立的空间(栈帧)创建局部变量,它不是共享的资源。局部变量包括方法的**参数变量**和**方法内定义的变量**; 3)每次调用方法前都新建一个实例是线程安全的,因为不会访问共享的资源。 4)成员变量会受到多线程影响,成员变量包括**实例变量**和**类变量(静态变量)**; 5)对于成员变量的操作,可以使用ThreadLocal来保证线程安全;