SpringMVC中Controller是单例还是多例?如何保证并发安全?

【SpringMVC】Controller之单例模式 单例模式 作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问入口 1、举栗子 1.Windows的任务管理器 2.Windows的回收站,也是一个单例应用 3.SpringMVC的控制器 2、优点 1.减少了系统的性能开销,当一个对象需要产生时,当时消耗的资源较多。那么产生对象时构建的方式就可以通过单例去构建。 2.单例模式存在全局访问点,所以可以优化共享资源访问。 3、常见... 阅读详情

单例模式(Singleton)是程序设计中一种非常重要的设计模式,设计模式也是Java面试重点考察的一个方面。面试经常会问到的一个问题是:SpringMVC中的Controller是单例还是多例,很多同学可能会想当然认为Controller是多例,其实不然。

图片

Tomcat官网截图

根据Tomcat官网中的介绍,对于一个浏览器请求,tomcat会指定一个处理线程,或是在线程池中选取空闲的,或者新建一个线程。

Each incoming request requires a thread for the duration of that request. If more simultaneous requests are received than can be handled by the currently available request processing threads, additional threads will be created up to the configured maximum (the value of the maxThreads attribute). If still more simultaneous requests are received, they are stacked up inside the server socket created by the Connector, up to the configured maximum (the value of the acceptCountattribute). Any further simultaneous requests will receive "connection refused" errors, until resources are available to process them.

—— https://tomcat.apache.org/tomcat-7.0-doc/config/http.html

在Tomcat容器中,每个servlet是单例的。在SpringMVC中,Controller 默认也是单例。 采用单例模式的最大好处,就是可以在高并发场景下极大地节省内存资源,提高服务抗压能力。

单例模式容易出现的问题是:在Controller中定义的实例变量,在多个请求并发时会出现竞争访问,Controller中的实例变量不是线程安全的。

Controller不是线程安全的

正因为Controller默认是单例,所以不是线程安全的。如果用SpringMVC的 Controller时,尽量不在 Controller中使用实例变量,否则会出现线程不安全性的情况,导致数据逻辑混乱。

举一个简单的例子,在一个Controller中定义一个非静态成员变量 num 。通过Controller成员方法来对 num 增加。

@Controller
public class TestController {
    private int num = 0;

    @RequestMapping("/addNum")
    public void addNum() {
        System.out.println(++num);
    }
}

在本地运行后:

  • 首先访问 http://localhost:8080/addNum,得到的答案是1;

  • 再次访问 http://localhost:8080/addNum,得到的答案是 2。

两次访问得到的结果不同,num已经被修改,并不是我们希望的结果,接口的幂等性被破坏。

从这个例子可以看出,所有的请求访问同一个Controller实例,Controller的私有成员变量就是线程共用的。某个请求对应的线程如果修改了这个变量,那么在别的请求中也可以读到这个变量修改后的的值。

Controller并发安全的解决办法

如果要保证Controller的线程安全,有以下解决办法:

  • 尽量不要在 Controller 中定义成员变量;

如果必须要定义一个非静态成员变量,那么可以通过注解@Scope("prototype"),将Controller设置为多例模式。

@Controller
@Scope(value="prototype")
public class TestController {
    private int num = 0;

    @RequestMapping("/addNum")
    public void addNum() {
        System.out.println(++num);
    }
}

Scope属性是用来声明IOC容器中的对象(Bean )允许存在的限定场景,或者说是对象的存活空间。在对象进入相应的使用场景之前,IOC容器会生成并装配这些对象;当该对象不再处于这些使用场景的限定时,容器通常会销毁这些对象。

推荐划水摸鱼神器:

https://www.yoodb.com/slack-off/home.html

Controller也是一个​​​​​​​Bean,默认的 Scope 属性为Singleton ,也就是单例模式。如果Bean的 Scope 属性设置为 prototype 的话,容器在接受到该类型对象的请求时,每次都会重新生成一个新的对象给请求方。

  • Controller 中使用​​​​​​​ThreadLocal​​​​​​​变量。每一个线程都有一个变量的副本。

public class TestController {
    private int num = 0;
    private final ThreadLocal <Integer> uniqueNum =
             new ThreadLocal <Integer> () {
                 @Override protected Integer initialValue() {
                     return num;
                 }
             };

    @RequestMapping("/addNum")
    public void addNum() {
        int unum = uniqueNum.get();
       uniqueNum.set(++unum);
       System.out.println(uniqueNum.get());
    }
}

以上代码运行以后,每次请求 http://localhost:8080/addNum , 得到的结果都是1。

更严格的做法是用AtomicInteger类型定义成员变量,对于成员变量的操作使用AtomicInteger的自增方法完成。

总的来说,还是尽量不要在 Controller 中定义成员变量为好。

探究Spring中的Controller:单例、多例及其并发安全性 Spring框架作为Java生态系统中的重要一员,极大地方便了Java企业级应用的开发。其中,Spring MVC(Model-View-Controller)是Spring框架中的核心模块之一,主要用于构建Web应用程序。在Spring MVC中,`Controller`是处理用户请求的关键组件。那么,Spring中的Controller到底是单例(singleton)还是多例(prototype)?在单例模式下,如何保证并发的安全性?本文将从以下几个方面深入探讨这些问题。 阅读详情

相关推荐

目标检测——布匹缺陷检测数据集

结构瑕疵指的是布料本身的缺陷,包括嵌结、抽纱、错纱、断纱、预缩等问题,这些问题通常是在布料生产过程中出现的。而质量瑕疵则是指布料在使用过程中出现的问题,如污渍、断裂、鼓囊、针眼等,这些问题可能由生产过程中的结构瑕疵导致,也可能是在运输、存放和使用过程中引起的。布匹瑕疵如缺纬、断纬、粗纬、松纬、缺经、断经、粗经、筘痕、污点、破损等,若未得到及时有效的检测,这些瑕疵产品可能会流向市场,导致消费者的不满和退货,严重影响企业的声誉和品牌形象。织疵包括缺经、缺纬、跳花、弓纱、错纱、厚薄段、油污渍等;

zzjlhlcd的博客 612

SpringMVC中的Controller是单例模式吗?如果是,为什么其可以支持多线程访问?

SpringMVC中Controller默认情况下是单例模式(可通过@Scope(value="prototype")设置为多例) 先来看一下默认情况下: @Controller @RequestMapping(value = "/springTest") public class SpringMvcController { public Map<String,Object&g...

编程界的一名小学生 9942

电路研究9.4——合宙Air780EP的LuatOS、CSDK跟标准AT

 C-SDK、AT指令、LuatOS

esmember的博客 1116

Spring MVC的Controller控制器默认是单例模式会带来什么问题?怎么解决?

避免使用可变的实例变量:控制器应尽量避免使用实例变量,或者确保实例变量的使用是线程安全的。选择合适的方法取决于具体的需求和场景。使用线程安全的控制器:如果控制器中确实需要使用共享的实例变量,可以采取措施保证线程安全,例如使用同步机制或使用线程安全的数据结构。状态共享问题:由于控制器是单例的,如果在控制器中存在可变的状态,那么多个请求之间可能会共享这些状态,导致数据混乱或不一致的结果。使用原型模式:如果控制器的状态对每个请求都是独立的,可以将控制器配置为原型模式,这样每个请求都会创建一个新的控制器实例。

学亮编程手记 480

STM32F0实现数字化SPWM纯正弦波逆变器

这个没啥好说的,搭电路的事。其核心思想是两边桥臂分别由两个180度相位差的正弦波与三角载波比较来控制,优点是在开关器件工作频率一样的情况下,输出PWM频率是单极性SPWM的2倍,能够明显减少谐波,因此只需要相对较小的电感和电容滤波器件就可以起到很好的滤波效果,提升了系统的性能,也精简了系统体积,降低了成本。而双极性pwm则是在整个正弦周期内,四只管子都在高频开关状态工作,对角线上的管子一起导通,另一对角线上管子互补导通,实际上只需要一路互补的PWM控制,负载上电压在正电压和负电压之间切换,不出现0v。

forlifefor的专栏 1万+

论文精读-ReTransformer ReRAM-based Processing-in-MemoryArchitecture for Transformer Acceleration

Transformer已经成为一种流行的深度神经网络(DNN)模型,用于神经语言处理(NLP)应用,并在神经机器翻译、实体识别等方面表现出优异的性能。然而,其在自回归解码器中的规模化点积注意机制在推理过程中带来了性能瓶颈。Transformer也是计算和内存密集型的,需要硬件加速解决方案。

a284365的博客 1922

如何保证 Controller 的并发安全?

程序员的成长之路互联网/程序员/技术/资料共享关注阅读本文大概需要 2.8 分钟。来自:toutiao.com/article/6927297421139706376单例模式(Singleton)是程序设计中一种非常重要的设计模式,设计模式也是Java面试重点考察的一个方面。面试经常会问到的一个问题是:SpringMVC中的Controller是单例还是多例,很多同学可...

良月柒 636

量子纠缠态与AI意识模型的探索

摘要 本文探讨量子纠缠态与AI意识模型的关联性研究。从量子力学基本原理出发,分析量子纠缠的非局域性特征及其与意识整合性的潜在联系。DREAMVFIA团队构建了量子-意识统一理论框架,提出量子纠缠态意识理论(QETC)和量子化整合信息度量(Q-IIT)等创新理论。在实践层面,开发了基于量子纠缠的QNN-C神经网络架构和量子意识度量算法,实验证明量子机制可显著提升AI系统的认知灵活性、信息整合能力和元认知水平。研究为理解意识本质和开发具有意识特征的人工智能系统提供了新的理论框架和技术路径。

梦帮科技开源中心 1142

SpringMVC中的控制器是不是单例模式?如果是,如何保证线程安全?

(2)最好的方式是将控制器设置为无状态模式,在控制器中,不要携带数据。但可以引用无状态的service和dao。(1)将scope设置成非singleton,比如protype,request。单例模式下会有线程安全。控制器是单例模式的。

weixin_49131718的博客 314

[软考]系统架构设计师 备考经验分享(一) - 备考计划篇

前言 上周末刚刚结束了软考架构师的考试,自我感觉考的还可以,大概率是过了。 两次参加软考,一次中级嵌入式,一次高级架构师,都是备考不到两个月时间,尤其是架构师这次考试内容和本职工作有不小的差别,并且需要同时备考三个科目,在高强度地备考中感觉是摸索出到了一点软考的技巧与经验。 打算趁还记得,赶紧写几篇文章做下梳理总结,算是给将来自己考系分、高项或者其他考试做个记录,也希望能够帮到正在备考的大家。 先把第一步,个人的备考计划分享给大家。 自身情况分析 首先,请大家一定先明确三个问题,这三个问题会直接影响到你的

_ 6404

Coze 上 OpenClaw 完整使用攻略(零代码 + 24 小时在线 + 飞书 / 微信接入)

Coze(扣子)是目前国内零门槛部署 OpenClaw 最友好的平台,无需服务器、不用命令行,5 分钟即可拥有可执行本地 / 云端任务的 AI 助手,还能一键发布到飞书、微信、钉钉等 IM。

hy行者勇哥的博客 2921

SpringMVC 中 Controller 是单例还是多例?如何保证并发安全?

点击上方“Java精选”,选择“设为星标”别问别人为什么,多问自己凭什么!下方有惊喜留言必回,有问必答!每一天进步一点点,是成功的开始...单例模式(Singleton)是程序设计中一种非常重要的设计模式,设计模式也是Java面试重点考察的一个方面。面试经常会问到的一个问题是:SpringMVC中的Controller是单例还是多例,很多同学可能会想当然认为Control...

Java精选 1696

大模型部署指南:SGLang 框架

本文介绍使用 SGLang 框架部署大模型

举世誉之而不加劝,举世非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。 1611

SpringMVC中的Controller是单例还是多例,怎么保证并发的安全。

controller默认是单例的,不要使用非静态的成员变量,否则会发生数据逻辑混乱。 正因为单例所以不是线程安全的。 package com.riemann.springbootdemo.controller; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Co...

qq_37432174的博客 2434

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

SpringMVC使用注意点,由spring的controller是单例还是多例,怎么保证并发的安全问题思考

答案 controller默认是单例的,不要使用非静态的成员变量,否则会发生数据逻辑混乱。 正因为单例所以不是线程安全的。 验证 我们下面来简单的验证下: package com.riemann.springbootdemo.controller; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import org.springframework.

xtho62的博客 401

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

(转帖)SpringMVC 中 Controller 是单例还是多例?如何保证并发安全?

SpringMVC 中 Controller 是单例还是多例?

cleble的专栏 226

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

阿里一面:如何保证 Controller 的并发安全?

点击关注公众号,Java干货及时送达????单例模式(Singleton)是程序设计中一种非常重要的设计模式,设计模式也是Java面试重点考察的一个方面。面试经常会问到的一个问题是:SpringMVC中的Controller是单例还是多例,很多同学可能会想当然认为Controller是多例,其实不然。Tomcat官网截图根据Tomcat官网中的介绍,对于一个浏览器请求,tomc...

这个时代,作为程序员可能要学习小程序 346

保证 Controller 的并发安全

SpringMVC中的Controller是单例, 因为在Tomcat容器中,每个servlet是单例的。在SpringMVC中,Controller 默认也是单例。 采用单例模式的最大好处,就是可以在高并发场景下极大地节省内存资源,提高服务抗压能力。单例的Controller有个问题就是: 在Controller中定义的实例变量,在多个请求并发时会出现竞争访问,Controller中的实例变量不是线程安全的。 示例: @Controller public class TestController {

qq_31511385的博客 406

spring-web开发中的并发问题

springMVC-controller 中的并发问题 在Tomcat容器中,每个servlet是单例的。在SpringMVC中,Controller 默认也是单例。 采用单例模式的最大好处,就是可以在高并发场景下极大地节省内存资源,提高服务抗压能力(不用每次创建Controller,减少了对象创建和垃圾收集的时间。)。 Spring中的Bean默认都是单例。 当有多个用户同时请求一个服务时,容器会给每一个请求分配一个线程,各个线程是不会相互影响, 单例模式容易出现的问题是:在Controller中定义.

guanglizI的专栏 569

Spring的Controller是单例还是多例,如何保证并发的安全?

Controller默认是单例的,不要使用非静态的成员变量,否则会发生数据逻辑混乱。** 正因为单例所以不是线程安全的。 如下代码: package com.riemann.springbootdemo.controller; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import org.springframework.web.bind.an

Venus's Blog 2万+

Spring的Controller是单例还是多例,如何保证线程安全的。

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

青衫烟雨客的专栏 4541

SpringMVC如何保证Controller的并发安全

SpringMVC如何保证Controller的并发安全,超详细案例

末尾卡片和博主交流学习! 1687

Spring MVC 中是如何保证Controller的并发安全?

Spring MVC 保证Controller单例无状态设计默认是单例,因此控制器应设计为无状态。避免使用共享的可变实例变量:控制器中不应包含任何共享的可变实例变量,以免在并发访问时发生线程安全问题。使用存储线程独立的临时状态:当需要共享一些临时状态时,使用来隔离数据。使用局部变量存储临时数据:将中间状态或临时数据存储在局部变量中,以确保每个请求的隔离性和线程安全。通过这些设计原则和代码实践,Spring MVC 的Controller能够在高并发环境中有效保证线程安全。

每日一贴 1868
上一篇: Go 负责人说以后不会有 Go2 了
下一篇: 前端断点调试是如何实现的?
IT界那些事儿
博客等级 码龄6年 2万+粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值