spring的controller是单例还是多例,怎么保证并发的安全

Java学习之道

共 1156字,需浏览 3分钟

 ·

2022-05-22 08:18

关注Java学习之道一起成长,一起学习~

作者: 淼淼之森
来源: blog.csdn.net/qq516071744/article/details/89005077

Part1

controller默认是单例的,不要使用非静态的成员变量,否则会发生数据逻辑混乱。正因为单例所以不是线程安全的。

@Controller
public class ScopeTestController {
  
    private int num = 0;
  
    @RequestMapping("/testScope")
    public void testScope() {
        System.out.println(++num);
    }
  
    @RequestMapping("/testScope2")
    public void testScope2() {
        System.out.println(++num);
    }
  
}
  1. 首先访问 http://localhost:8080/testScope,得到的答案是1;单例是不安全的,会导致属性重复使用。
  2. 然后我们再访问 http://localhost:8080/testScope2,得到的答案是 2。此时就不是我们想要的答案,num已经被修改。所有 request都访问同一个 Controller时,这里的私有变量就是共用的,也就是说某个 request中如果修改了这个变量,那么在别的请求中也可读到这个修改的内容。

Part2解决方案

  1. 不要在controller中定义成员变量。
  2. 万一必须要定义一个非静态成员变量时候,则通过注解@Scope(“prototype”),将其设置为多例模式。(设置controller为多例模式 ,每次都创建新的controller;)在Controller中使用ThreadLocal变量
  3. 比如:private ThreadLocal\ count = new ThreadLocal\();

ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。另外,对集合的使用最好使用并发包里面的线程安全类。

-- END --

 | 更多精彩文章 -



← 左右滑动与Java学习之道互动交流 →

加我微信,交个朋友
长按/扫码添加↑↑↑


浏览 10
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报