Spring解决创建单例bean,而存在线程不安全问题,的解决方案
一、线程安全问题都是由全局变量、静态变量和类的成员变量引起的。若每个线程中对全局变量、静态变量和类的成员变量只有读操作,而无写
操作,一般来说,这个全局变量是线程安全的,反之线程存在问题
二、因为Spring中的Bean默认是单例的,所以在定义成员变量时也有可能会发生线程安全问题。
三、解决方案
A、在对应的类名上加上该注解@Scope("prototype")从而将默认的@Scope("")改为多例,表示每次调用该接口都会生成一个新的Bean。
B、ThreadLocal解决问题
ThreadLocal作用:为每个使用该变量【全局变量、静态变量和类的成员变量】的线程分配一个独立的变量,从而互不影响
ThreadLocal底层原理:是一个Map,key:Thread.currentThread() value:变量
@RestController
//@Scope("prototype")
public class BeanController {
private static ThreadLocal<Integer> content = new ThreadLocal<Integer>() {
@Override
protected Integer initialValue() {
return (int)(Math.random()*10+100);
}
};
private static ThreadLocal<String> test = new ThreadLocal<String>() {
@Override
protected String initialValue() {
return "单例模式是不安全的"+(int)(Math.random()*10+100);
}
};
@RequestMapping("testBean")
public Object getSercurity(){
System.out.println(content.get());
System.out.println(test.get()); System.out.println();
return test.get();
}
}
C、三种解决方案:尽量不要使用成员变量
D、四种解决方案:
前提:该程序是web应用,可以使用Spring Bean的作用域中的request,就是说在类前面加上@Scope("request"),表明每次请求都会生成一个新的Bean对象。作用于@Scope("prototype")类似。
链接地址:https://blog.csdn.net/weixin_42324471/article/details/90603651