Springboot tomcat bean 默认作用域 singleton 情况下模拟线程不安全情况 设置多例方式 prototype

这篇具有很好参考价值的文章主要介绍了Springboot tomcat bean 默认作用域 singleton 情况下模拟线程不安全情况 设置多例方式 prototype。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

写一个控制层的类

验证方法

​编辑

分别执行如下请求,先执行等待时间久的

日志结果

结论

配置多例模式

配置文件application.properties

类加注解

配置类方式

增加验证 控制层  服务层 都是  singleton 模式情况 模拟线程不安全情况

service 代码

ctr

测试方式

运行日志

结论

加上prototype试下效果 线程安全

service

ctr 

调用

日志

结论




写一个控制层的类

package com.example.ctr;
 
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
@Slf4j
public class Api {
       int cc = 0;
    static int ccs = 0;
    @RequestMapping("/sleep/{num}")
    public String sleep(@PathVariable int num) throws InterruptedException {
        cc = num;
        ccs = num;
        int s = num;
        log.info(Thread.currentThread().getName()+" "+num+"  start  方法级变量="+s+"类级变量=" +cc +" 类级静态变量="+ccs);
        Thread.sleep(num);
        log.info(Thread.currentThread().getName()+" "+num+" end   方法级变量="+s+"类级变量=" +cc +" 类级静态变量="+ccs);
        return "ok   方法级变量="+s+"类级变量=" +cc +" 类级静态变量="+ccs;
    }

}

验证方法

Springboot tomcat bean 默认作用域 singleton 情况下模拟线程不安全情况 设置多例方式 prototype,java,spring boot,spring boot,tomcat,单例模式

分别执行如下请求,先执行等待时间久的

http://localhost:8101/api/sleep/60000

http://localhost:8101/api/sleep/30000

http://localhost:8101/api/sleep/10000

http://localhost:8101/api/sleep/5000

http://localhost:8101/api/sleep/1000

日志结果

2023-07-03 14:19:06.616  INFO 33444 --- [nio-8101-exec-1] com.example.ctr.Api                      : http-nio-8101-exec-1 60000  start  方法级变量=60000类级变量=60000 类级静态变量=60000
2023-07-03 14:19:07.171  INFO 33444 --- [nio-8101-exec-2] com.example.ctr.Api                      : http-nio-8101-exec-2 30000  start  方法级变量=30000类级变量=30000 类级静态变量=30000
2023-07-03 14:19:08.318  INFO 33444 --- [nio-8101-exec-3] com.example.ctr.Api                      : http-nio-8101-exec-3 10000  start  方法级变量=10000类级变量=10000 类级静态变量=10000
2023-07-03 14:19:09.705  INFO 33444 --- [nio-8101-exec-4] com.example.ctr.Api                      : http-nio-8101-exec-4 5000  start  方法级变量=5000类级变量=5000 类级静态变量=5000
2023-07-03 14:19:11.277  INFO 33444 --- [nio-8101-exec-5] com.example.ctr.Api                      : http-nio-8101-exec-5 1000  start  方法级变量=1000类级变量=1000 类级静态变量=1000
2023-07-03 14:19:12.286  INFO 33444 --- [nio-8101-exec-5] com.example.ctr.Api                      : http-nio-8101-exec-5 1000 end   方法级变量=1000类级变量=1000 类级静态变量=1000
2023-07-03 14:19:14.707  INFO 33444 --- [nio-8101-exec-4] com.example.ctr.Api                      : http-nio-8101-exec-4 5000 end   方法级变量=5000类级变量=1000 类级静态变量=1000
2023-07-03 14:19:18.322  INFO 33444 --- [nio-8101-exec-3] com.example.ctr.Api                      : http-nio-8101-exec-3 10000 end   方法级变量=10000类级变量=1000 类级静态变量=1000
2023-07-03 14:19:37.181  INFO 33444 --- [nio-8101-exec-2] com.example.ctr.Api                      : http-nio-8101-exec-2 30000 end   方法级变量=30000类级变量=1000 类级静态变量=1000
2023-07-03 14:20:06.628  INFO 33444 --- [nio-8101-exec-1] com.example.ctr.Api                      : http-nio-8101-exec-1 60000 end   方法级变量=60000类级变量=1000 类级静态变量=1000

可见 执行久的线程,在运行中 对象级的变量,再新请求来后变量发生改变

结论

方法级变量线程安全

对象级变量和静态变量都不安全

ok

持续更新文章来源地址https://www.toymoban.com/news/detail-517716.html

配置多例模式

配置文件application.properties

spring.main.allow-bean-definition-overriding=true

类加注解

@Component
@Scope("prototype")
public class MyBean {
    //...
}

配置类方式

@Configuration
public class MyConfig {
    @Bean
    @Scope("prototype")
    public MyBean myBean(){
        return new MyBean();
    }
}

ok

持续更新

增加验证 控制层  服务层 都是  singleton 模式情况 模拟线程不安全情况

service 代码

package com.example.ctr;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class ApiServiceImpl {

    int cc = 0;
    static int ccs = 0;
    public String sleep(int num) throws InterruptedException {
        cc = num;
        ccs = num;
        int s = num;
        log.info("service "+Thread.currentThread().getName()+" "+num+"  start  方法级变量="+s+"类级变量=" +cc +" 类级静态变量="+ccs);
        Thread.sleep(num);
        log.info("service "+Thread.currentThread().getName()+" "+num+" end   方法级变量="+s+"类级变量=" +cc +" 类级静态变量="+ccs);
        return "service "+"ok   方法级变量="+s+"类级变量=" +cc +" 类级静态变量="+ccs;
    }
}

ctr

package com.example.ctr;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/api")
@Slf4j
public class Api {
    @Resource
    private ApiServiceImpl apiServiceImpl;
    int cc = 0;
    static int ccs = 0;
    @RequestMapping("/sleep/{num}")
    public String sleep(@PathVariable int num) throws InterruptedException {
        cc = num;
        ccs = num;
        int s = num;
        log.info("ctr "+Thread.currentThread().getName()+" "+num+"  start  方法级变量="+s+"类级变量=" +cc +" 类级静态变量="+ccs);
        Thread.sleep(num);
        log.info("ctr "+Thread.currentThread().getName()+" "+num+" end   方法级变量="+s+"类级变量=" +cc +" 类级静态变量="+ccs);
        String res = apiServiceImpl.sleep(num);
        return "ctr ok   方法级变量="+s+"类级变量=" +cc +" 类级静态变量="+ccs+"  "+res;
    }

}

测试方式

Springboot tomcat bean 默认作用域 singleton 情况下模拟线程不安全情况 设置多例方式 prototype,java,spring boot,spring boot,tomcat,单例模式

http://localhost:8101/api/sleep/5000

 http://localhost:8101/api/sleep/2000

http://localhost:8101/api/sleep/1000

运行日志

2023-07-04 09:55:34.827  INFO 21092 --- [io-8101-exec-10] com.example.ctr.ApiServiceImpl           : service http-nio-8101-exec-10 10000 end   方法级变量=10000类级变量=10000 类级静态变量=10000
2023-07-04 09:55:42.148  INFO 21092 --- [nio-8101-exec-9] com.example.ctr.Api                      : ctr http-nio-8101-exec-9 30000 end   方法级变量=30000类级变量=1000 类级静态变量=1000
2023-07-04 09:55:42.148  INFO 21092 --- [nio-8101-exec-9] com.example.ctr.ApiServiceImpl           : service http-nio-8101-exec-9 30000  start  方法级变量=30000类级变量=30000 类级静态变量=30000
2023-07-04 09:56:04.722  INFO 21092 --- [nio-8101-exec-7] com.example.ctr.Api                      : ctr http-nio-8101-exec-7 5000  start  方法级变量=5000类级变量=5000 类级静态变量=5000
2023-07-04 09:56:05.898  INFO 21092 --- [nio-8101-exec-6] com.example.ctr.Api                      : ctr http-nio-8101-exec-6 2000  start  方法级变量=2000类级变量=2000 类级静态变量=2000
2023-07-04 09:56:06.974  INFO 21092 --- [nio-8101-exec-1] com.example.ctr.Api                      : ctr http-nio-8101-exec-1 1000  start  方法级变量=1000类级变量=1000 类级静态变量=1000
2023-07-04 09:56:07.902  INFO 21092 --- [nio-8101-exec-6] com.example.ctr.Api                      : ctr http-nio-8101-exec-6 2000 end   方法级变量=2000类级变量=1000 类级静态变量=1000
2023-07-04 09:56:07.902  INFO 21092 --- [nio-8101-exec-6] com.example.ctr.ApiServiceImpl           : service http-nio-8101-exec-6 2000  start  方法级变量=2000类级变量=2000 类级静态变量=2000
2023-07-04 09:56:07.980  INFO 21092 --- [nio-8101-exec-1] com.example.ctr.Api                      : ctr http-nio-8101-exec-1 1000 end   方法级变量=1000类级变量=1000 类级静态变量=1000
2023-07-04 09:56:07.980  INFO 21092 --- [nio-8101-exec-1] com.example.ctr.ApiServiceImpl           : service http-nio-8101-exec-1 1000  start  方法级变量=1000类级变量=1000 类级静态变量=1000
2023-07-04 09:56:08.988  INFO 21092 --- [nio-8101-exec-1] com.example.ctr.ApiServiceImpl           : service http-nio-8101-exec-1 1000 end   方法级变量=1000类级变量=1000 类级静态变量=1000
2023-07-04 09:56:09.736  INFO 21092 --- [nio-8101-exec-7] com.example.ctr.Api                      : ctr http-nio-8101-exec-7 5000 end   方法级变量=5000类级变量=1000 类级静态变量=1000
2023-07-04 09:56:09.736  INFO 21092 --- [nio-8101-exec-7] com.example.ctr.ApiServiceImpl           : service http-nio-8101-exec-7 5000  start  方法级变量=5000类级变量=5000 类级静态变量=5000
2023-07-04 09:56:09.907  INFO 21092 --- [nio-8101-exec-6] com.example.ctr.ApiServiceImpl           : service http-nio-8101-exec-6 2000 end   方法级变量=2000类级变量=5000 类级静态变量=5000
2023-07-04 09:56:12.161  INFO 21092 --- [nio-8101-exec-9] com.example.ctr.ApiServiceImpl           : service http-nio-8101-exec-9 30000 end   方法级变量=30000类级变量=5000 类级静态变量=5000
2023-07-04 09:56:14.748  INFO 21092 --- [nio-8101-exec-7] com.example.ctr.ApiServiceImpl           : service http-nio-8101-exec-7 5000 end   方法级变量=5000类级变量=5000 类级静态变量=5000

结论

只要是对象层的变量在并发情况下会出现线程不安全情况

方法层值是安全情况

ok

持续更新

加上prototype试下效果 线程安全

service

package com.example.ctr;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

@Service
@Slf4j
@Scope("prototype")
public class ApiServiceImpl {

    int cc = 0;
    static int ccs = 0;
    public String sleep(int num) throws InterruptedException {
        cc = num;
        ccs = num;
        int s = num;
        log.info("service "+Thread.currentThread().getName()+" "+num+"  start  方法级变量="+s+"类级变量=" +cc +" 类级静态变量="+ccs);
        Thread.sleep(num);
        log.info("service "+Thread.currentThread().getName()+" "+num+" end   方法级变量="+s+"类级变量=" +cc +" 类级静态变量="+ccs);
        return "service "+"ok   方法级变量="+s+"类级变量=" +cc +" 类级静态变量="+ccs;
    }
}

ctr 

package com.example.ctr;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/api")
@Slf4j
@Scope("prototype")
public class Api {
    @Resource
    private ApiServiceImpl apiServiceImpl;
    int cc = 0;
    static int ccs = 0;
    @RequestMapping("/sleep/{num}")
    public String sleep(@PathVariable int num) throws InterruptedException {
        cc = num;
        ccs = num;
        int s = num;
        log.info("ctr "+Thread.currentThread().getName()+" "+num+"  start  方法级变量="+s+"类级变量=" +cc +" 类级静态变量="+ccs);
        Thread.sleep(num);
        log.info("ctr "+Thread.currentThread().getName()+" "+num+" end   方法级变量="+s+"类级变量=" +cc +" 类级静态变量="+ccs);
        String res = apiServiceImpl.sleep(num);
        return "ctr ok   方法级变量="+s+"类级变量=" +cc +" 类级静态变量="+ccs+"  "+res;
    }

}

调用

同上方一样

日志

2023-07-04 10:05:51.245  INFO 34548 --- [nio-8101-exec-2] com.example.ctr.Api                      : ctr http-nio-8101-exec-2 5000  start  方法级变量=5000类级变量=5000 类级静态变量=5000
2023-07-04 10:05:51.683  INFO 34548 --- [nio-8101-exec-1] com.example.ctr.Api                      : ctr http-nio-8101-exec-1 2000  start  方法级变量=2000类级变量=2000 类级静态变量=2000
2023-07-04 10:05:52.842  INFO 34548 --- [nio-8101-exec-3] com.example.ctr.Api                      : ctr http-nio-8101-exec-3 1000  start  方法级变量=1000类级变量=1000 类级静态变量=1000
2023-07-04 10:05:53.696  INFO 34548 --- [nio-8101-exec-1] com.example.ctr.Api                      : ctr http-nio-8101-exec-1 2000 end   方法级变量=2000类级变量=2000 类级静态变量=1000
2023-07-04 10:05:53.696  INFO 34548 --- [nio-8101-exec-1] com.example.ctr.ApiServiceImpl           : service http-nio-8101-exec-1 2000  start  方法级变量=2000类级变量=2000 类级静态变量=2000
2023-07-04 10:05:53.851  INFO 34548 --- [nio-8101-exec-3] com.example.ctr.Api                      : ctr http-nio-8101-exec-3 1000 end   方法级变量=1000类级变量=1000 类级静态变量=1000
2023-07-04 10:05:53.851  INFO 34548 --- [nio-8101-exec-3] com.example.ctr.ApiServiceImpl           : service http-nio-8101-exec-3 1000  start  方法级变量=1000类级变量=1000 类级静态变量=1000
2023-07-04 10:05:54.858  INFO 34548 --- [nio-8101-exec-3] com.example.ctr.ApiServiceImpl           : service http-nio-8101-exec-3 1000 end   方法级变量=1000类级变量=1000 类级静态变量=1000
2023-07-04 10:05:55.698  INFO 34548 --- [nio-8101-exec-1] com.example.ctr.ApiServiceImpl           : service http-nio-8101-exec-1 2000 end   方法级变量=2000类级变量=2000 类级静态变量=1000
2023-07-04 10:05:56.259  INFO 34548 --- [nio-8101-exec-2] com.example.ctr.Api                      : ctr http-nio-8101-exec-2 5000 end   方法级变量=5000类级变量=5000 类级静态变量=1000
2023-07-04 10:05:56.259  INFO 34548 --- [nio-8101-exec-2] com.example.ctr.ApiServiceImpl           : service http-nio-8101-exec-2 5000  start  方法级变量=5000类级变量=5000 类级静态变量=5000
2023-07-04 10:06:01.268  INFO 34548 --- [nio-8101-exec-2] com.example.ctr.ApiServiceImpl           : service http-nio-8101-exec-2 5000 end   方法级变量=5000类级变量=5000 类级静态变量=5000

结论

加上prototype 线程安全 每次调用bean 创建对象

类级变量是线程安全的

ok

持续更新

到了这里,关于Springboot tomcat bean 默认作用域 singleton 情况下模拟线程不安全情况 设置多例方式 prototype的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring 6.0官方文档示例(22): singleton类型的bean和prototype类型的bean协同工作的方法(一)

    一、配置文件: 二、实体类 三、主类:

    2024年02月15日
    浏览(36)
  • Spring 6.0官方文档示例(23): singleton类型的bean和prototype类型的bean协同工作的方法(二)

    使用lookup-method: 一、实体类: 二、配置文件: 三、主类:

    2024年02月15日
    浏览(35)
  • 手写模拟SpringBoot核心流程(二):实现Tomcat和Jetty的切换

    上一篇文章我们聊到,SpringBoot中内置了web服务器,包括Tomcat、Jetty,并且实现了SpringBoot启动Tomcat的流程。 那么SpringBoot怎样自动切换成Jetty服务器呢? 接下来我们继续学习如何实现Tomcat和Jetty的自动切换。 将BerSpringApplication类中startTomcat写到TomcatWebServer实现类中。 JettyWebServe

    2024年02月12日
    浏览(40)
  • spring复习:(50)@Configuration注解配置的singleton的bean是什么时候被创建出来并缓存到容器的?

    一、主类: 二、配置类: 三、singleton bean的创建流程 运行到context.refresh(); 进入refresh方法: 向下运行到红线位置时: 会实例化所有的singleton bean.进入finisheBeanFactoryInitialization方法: 向下拖动代码,可以看到beanFactory.preInstantiateSingletons(); 进入preInstantiateSingletons方法: 可以看

    2024年02月16日
    浏览(38)
  • Spring Bean 的作用域(Bean Scope)

    大家好,我是 god23bin,今天我们来聊一聊 Spring 框架中的 Bean 作用域(Scope)。 我们在以 XML 作为配置元数据的情况下,进行 Bean 的定义,是这样的: 我们写了一个 Bean 定义(Bean Definition),就是用于创建所定义的类的实例的。 一个 Bean 定义,我们可以类比一个类的定义,你

    2024年02月09日
    浏览(41)
  • Spring bean定义&Spring Bean 的作用域

    目录 Spring bean定义   Spring配置元数据 Spring Bean 的作用域   singleton作用域:   原型作用域: 示例:   形成应用程序的骨干是由Spring IoC容器所管理的对象称为bean。bean被实例化,组装,并通过Spring IoC容器所管理的对象。这些bean由容器提供,例如,在XML的bean/定义,已经看到了

    2024年02月08日
    浏览(43)
  • Bean 的六种作用域

      目录 一、作用域是什么? 1、singleton(单例作用域) 2、prototype(原型作用域) 3、request(请求作用域) 4、session(回话作用域) 5、application(全局作用域) 6、websocket( HTTP WebSocket 作用域) 二、单例作⽤域VS 全局作⽤域 三、设置作用域 Bean的作用域是指Bean实例的生命周

    2024年02月10日
    浏览(40)
  • 【Spring】Bean的作用域

    根据 【动力节点】最新Spring框架教程,全网首套Spring6教程,跟老杜从零学spring入门到高级 以及老杜的原版笔记 https://www.yuque.com/docs/share/866abad4-7106-45e7-afcd-245a733b073f?# 《Spring6》 进行整理, 文档密码:mg9b Spring 相关文章整理汇总归纳于:https://www.yuque.com/u27599042/zuisie singleto

    2024年02月14日
    浏览(47)
  • 关于Bean的六种作用域

    在JavaSE中,我们学习过了全局变量以及局部变量,这里就涉及到了作用域问题,那么什么是作用域呢? 限定程序中变量的使用范围叫做作用域,或者说在源代码中定义变量的某个区域就叫做作用域。 而Bean的作用域指的是 Bean在Spring整个框架中的某种行为模式 , 比如singleto

    2024年02月08日
    浏览(52)
  • Bean 作用域和生命周期

    Spring 容器是用来存储和读取 Bean 的 , 因此 Bean 是 Spring 中最核心的操作资源. 编写代码过程中 , bean 对象如果有多个属性 , 创建 Getter , Setter, 构造方法 等方法 , 会产生大量冗长的代码. 那么为了使代码更加简洁 , 我们可以使用 Lombok 框架 , 只需要一行注释 , 就可以避免大量冗长

    2024年02月05日
    浏览(79)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包