首先,让我们弄清楚各种变量的区别: 成员变量、全局变量、实例变量、类变量、静态变量和局部变量的区别
Spring框架里的bean,或者说组件,获取实例的时候都是默认的单例模式,单例模式的意思就是只有一个实例当多用户同时请求一个服务时,容器会给每一个请求分配一个线程,这是多个线程会并发执行该请求多对应的业务逻辑(成员方法),此时就要注意了,如果该处理逻辑中有对该单列状态的修改(体现为该单列的成员属性),则必须考虑线程同步问题
一.单例模式有全局变量存在的问题
目前我们的系统中,Bean都是采取的单例模式,也就是在使用有 @Service 注解的类时都是采用 @Autowired。如果在 Bean 中 有全局变量,则由于该Bean 只有一个实例,当多用户访问统一接口时,Spring 采用多线程的方式去操作这个Bean ,这个全局变量也就可能存在线程不安问题。
1.1 线程不安全测试
Service
@Service
public class ConcService {
private int i;
public void add() {
i++;
}
public int getI() {
return i;
}
}
Controller
@RestController
@RequestMapping("conc")
public class ConcController {
@Autowired
private ConcService concService;
@GetMapping("/addi")
public void addI() {
concService.add();
}
@GetMapping("/geti")
public int getI() {
return concService.getI();
}
}
concService