点击上方 Java后端,选择 设为星标
优质文章,及时送达
-
singleton:单例,默认作用域。
-
prototype:原型,每次创建一个新对象。
-
request:请求,每次Http请求创建一个新对象,适用于WebApplicationContext环境下。
-
session:会话,同一个会话共享一个实例,不同会话使用不用的实例。
-
global-session:全局会话,所有会话共享一个实例。
spring单例,为什么controller、service和dao确能保证线程安全?
-
有状态就是有数据存储功能
-
无状态就是不会保存数据 controller、service和dao层本身并不是线程安全的,只是如果只是调用里面的方法,而且多线程调用一个实例的方法,会在内存中复制变量,这是自己的线程的工作内存,是安全的。
Java虚拟机栈是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
局部变量的固有属性之一就是封闭在执行线程中。它们位于执行线程的栈中,其他线程无法访问这个栈。
首先问@Controller @Service是不是线程安全的?
@RestController
public class TestController {
private int var = 0;
@GetMapping(value = "/test_var")
public String test() {
System.out.println("普通变量var:" + (++var));
return "普通变量var:" + var ;
}
}
普通变量var:1
普通变量var:2
普通变量var:3
@RestController
@Scope(value = "prototype") // 加上@Scope注解,他有2个取值:单例-singleton 多实例-prototype
public class TestController {
private int var = 0;
@GetMapping(value = "/test_var")
public String test() {
System.out.println("普通变量var:" + (++var));
return "普通变量var:" + var ;
}
}
普通变量var:1
普通变量var:1
普通变量var:1
@RestController
@Scope(value = "prototype") // 加上@Scope注解,他有2个取值:单例-singleton 多实例-prototype
public class TestController {
private int var = 0;
private static int staticVar = 0;
@GetMapping(value = "/test_var")
public String test() {
System.out.println("普通变量var:" + (++var)+ "---静态变量staticVar:" + (++staticVar));
return "普通变量var:" + var + "静态变量staticVar:" + staticVar;
}
}
普通变量var:1---静态变量staticVar:1
普通变量var:1---静态变量staticVar:2
普通变量var:1---静态变量staticVar:3
@RestController
@Scope(value = "singleton") // prototype singleton
public class TestController {
private int var = 0; // 定义一个普通变量
private static int staticVar = 0; // 定义一个静态变量
@Value("${test-int}")
private int testInt; // 从配置文件中读取变量
ThreadLocal<Integer> tl = new ThreadLocal<>(); // 用ThreadLocal来封装变量
@Autowired
private User user; // 注入一个对象来封装变量
@GetMapping(value = "/test_var")
public String test() {
tl.set(1);
System.out.println("先取一下user对象中的值:"+user.getAge()+"===再取一下hashCode:"+user.hashCode());
user.setAge(1);
System.out.println("普通变量var:" + (++var) + "===静态变量staticVar:" + (++staticVar) + "===配置变量testInt:" + (++testInt)
+ "===ThreadLocal变量tl:" + tl.get()+"===注入变量user:" + user.getAge());
return "普通变量var:" + var + ",静态变量staticVar:" + staticVar + ",配置读取变量testInt:" + testInt + ",ThreadLocal变量tl:"
+ tl.get() + "注入变量user:" + user.getAge();
}
}
@Configuration
public class MyConfig {
@Bean
public User user(){
return new User();
}
}
先取一下user对象中的值:0===再取一下hashCode:241165852
普通变量var:1===静态变量staticVar:1===配置变量testInt:1===ThreadLocal变量tl:1===注入变量user:1
先取一下user对象中的值:1===再取一下hashCode:241165852
普通变量var:2===静态变量staticVar:2===配置变量testInt:2===ThreadLocal变量tl:1===注入变量user:1
先取一下user对象中的值:1===再取一下hashCode:241165852
普通变量var:3===静态变量staticVar:3===配置变量testInt:3===ThreadLocal变量tl:1===注入变量user:1
先取一下user对象中的值:0===再取一下hashCode:853315860
普通变量var:1===静态变量staticVar:1===配置变量testInt:1===ThreadLocal变量tl:1===注入变量user:1
先取一下user对象中的值:1===再取一下hashCode:853315860
普通变量var:1===静态变量staticVar:2===配置变量testInt:1===ThreadLocal变量tl:1===注入变量user:1
先取一下user对象中的值:1===再取一下hashCode:853315860
普通变量var:1===静态变量staticVar:3===配置变量testInt:1===ThreadLocal变量tl:1===注入变量user:1
public class MyConfig {
@Bean
@Scope(value = "prototype")
public User user(){
return new User();
}
}
先取一下user对象中的值:0===再取一下hashCode:1612967699
普通变量var:1===静态变量staticVar:1===配置变量testInt:1===ThreadLocal变量tl:1===注入变量user:1
先取一下user对象中的值:0===再取一下hashCode:985418837
普通变量var:1===静态变量staticVar:2===配置变量testInt:1===ThreadLocal变量tl:1===注入变量user:1
先取一下user对象中的值:0===再取一下hashCode:1958952789
普通变量var:1===静态变量staticVar:3===配置变量testInt:1===ThreadLocal变量tl:1===注入变量user:1
作者:myseries
cnblogs.com/myseries/p/11729800.html
最近整理一份面试资料《Java技术栈学习手册》,覆盖了Java技术、面试题精选、Spring全家桶、Nginx、SSM、微服务、数据库、数据结构、架构等等。 获取方式:点“ 在看,关注公众号 Java后端 并回复 777 领取,更多内容陆续奉上。 推 荐 阅 读 1. 把 Spring Cloud 给拆了!你知道每个组件的原理吗? 2. 给你的 MyBatis-Plus 装上批量插入的翅膀 3. 36 张图梳理 Intellij IDEA 常用设置 4. 图解 SQL 5. 讨论:Service层需要接口吗?
喜欢文章,点个 在看
本文分享自微信公众号 - Java后端(web_resource)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
相关文章
暂无评论...