Spring 中的 Controller 和Service是線程安全的嗎?

作者:myseries
cnblogs.com/myseries/p/11729800.html
singleton:單例,默認(rèn)作用域。
prototype:原型,每次創(chuàng)建一個(gè)新對(duì)象。
request:請(qǐng)求,每次Http請(qǐng)求創(chuàng)建一個(gè)新對(duì)象,適用于WebApplicationContext環(huán)境下。
session:會(huì)話,同一個(gè)會(huì)話共享一個(gè)實(shí)例,不同會(huì)話使用不用的實(shí)例。
global-session:全局會(huì)話,所有會(huì)話共享一個(gè)實(shí)例。
spring單例,為什么controller、service和dao確能保證線程安全?
有狀態(tài)就是有數(shù)據(jù)存儲(chǔ)功能
無狀態(tài)就是不會(huì)保存數(shù)據(jù) controller、service和dao層本身并不是線程安全的,只是如果只是調(diào)用里面的方法,而且多線程調(diào)用一個(gè)實(shí)例的方法,會(huì)在內(nèi)存中復(fù)制變量,這是自己的線程的工作內(nèi)存,是安全的。
Java虛擬機(jī)棧是線程私有的,它的生命周期與線程相同。虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個(gè)方法在執(zhí)行的同時(shí)都會(huì)創(chuàng)建一個(gè)棧幀用于存儲(chǔ)局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口等信息。
局部變量的固有屬性之一就是封閉在執(zhí)行線程中。它們位于執(zhí)行線程的棧中,其他線程無法訪問這個(gè)棧。
首先問@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個(gè)取值:單例-singleton 多實(shí)例-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個(gè)取值:單例-singleton 多實(shí)例-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)+?"---靜態(tài)變量staticVar:"?+ (++staticVar));
????????return?"普通變量var:"?+?var?+?"靜態(tài)變量staticVar:"?+ staticVar;
????}
}普通變量var:1---靜態(tài)變量staticVar:1
普通變量var:1---靜態(tài)變量staticVar:2
普通變量var:1---靜態(tài)變量staticVar:3@RestController
@Scope(value?=?"singleton")?// prototype singleton
public?class?TestController?{
????private?int?var?=?0;?// 定義一個(gè)普通變量
????private?static?int?staticVar =?0;?// 定義一個(gè)靜態(tài)變量
????@Value("${test-int}")
????private?int?testInt;?// 從配置文件中讀取變量
????ThreadLocal tl =?new?ThreadLocal<>();?// 用ThreadLocal來封裝變量
????@Autowired
????private?User user;?// 注入一個(gè)對(duì)象來封裝變量
????@GetMapping(value?=?"/test_var")
????public?String?test()?{
????????tl.set(1);
????????System.out.println("先取一下user對(duì)象中的值:"+user.getAge()+"===再取一下hashCode:"+user.hashCode());
????????user.setAge(1);
????????System.out.println("普通變量var:"?+ (++var) +?"===靜態(tài)變量staticVar:"?+ (++staticVar) +?"===配置變量testInt:"?+ (++testInt)
????????????????+?"===ThreadLocal變量tl:"?+ tl.get()+"===注入變量user:"?+ user.getAge());
????????return?"普通變量var:"?+?var?+?",靜態(tài)變量staticVar:"?+ staticVar +?",配置讀取變量testInt:"?+ testInt +?",ThreadLocal變量tl:"
????????????????+ tl.get() +?"注入變量user:"?+ user.getAge();
????}
} @Configuration
public?class?MyConfig?{
????@Bean
????public?User?user(){
????????return?new?User();
????}
}先取一下user對(duì)象中的值:0===再取一下hashCode:241165852
普通變量var:1===靜態(tài)變量staticVar:1===配置變量testInt:1===ThreadLocal變量tl:1===注入變量user:1
先取一下user對(duì)象中的值:1===再取一下hashCode:241165852
普通變量var:2===靜態(tài)變量staticVar:2===配置變量testInt:2===ThreadLocal變量tl:1===注入變量user:1
先取一下user對(duì)象中的值:1===再取一下hashCode:241165852
普通變量var:3===靜態(tài)變量staticVar:3===配置變量testInt:3===ThreadLocal變量tl:1===注入變量user:1先取一下user對(duì)象中的值:0===再取一下hashCode:853315860
普通變量var:1===靜態(tài)變量staticVar:1===配置變量testInt:1===ThreadLocal變量tl:1===注入變量user:1
先取一下user對(duì)象中的值:1===再取一下hashCode:853315860
普通變量var:1===靜態(tài)變量staticVar:2===配置變量testInt:1===ThreadLocal變量tl:1===注入變量user:1
先取一下user對(duì)象中的值:1===再取一下hashCode:853315860
普通變量var:1===靜態(tài)變量staticVar:3===配置變量testInt:1===ThreadLocal變量tl:1===注入變量user:1public?class?MyConfig?{
????@Bean
????@Scope(value =?"prototype")
????public User user(){
????????return?new?User();
????}?
}先取一下user對(duì)象中的值:0===再取一下hashCode:1612967699
普通變量var:1===靜態(tài)變量staticVar:1===配置變量testInt:1===ThreadLocal變量tl:1===注入變量user:1
先取一下user對(duì)象中的值:0===再取一下hashCode:985418837
普通變量var:1===靜態(tài)變量staticVar:2===配置變量testInt:1===ThreadLocal變量tl:1===注入變量user:1
先取一下user對(duì)象中的值:0===再取一下hashCode:1958952789
普通變量var:1===靜態(tài)變量staticVar:3===配置變量testInt:1===ThreadLocal變量tl:1===注入變量user:1
springboot+redis+Interceptor+自定義annotation實(shí)現(xiàn)接口自動(dòng)冪等 100W個(gè)微信紅包封面,速度領(lǐng)取!!! API接口的安全設(shè)計(jì)驗(yàn)證:ticket,簽名,時(shí)間戳 牛逼,一份基于SSM框架實(shí)現(xiàn)的支付寶支付功能,附完整源代碼... Redis、Kafka或RabbitMQ,哪個(gè)更和微服務(wù)更般配? JDK 16 即將發(fā)布,看完這些新特性,我感覺已經(jīng)學(xué)不動(dòng)了.. Redis 分布式鎖使用不當(dāng),超賣了100瓶飛天茅臺(tái)!!! SQL優(yōu)化最干貨總結(jié)(2021最新版)
評(píng)論
圖片
表情
