av一区二区在线观看_亚洲男人的天堂网站_日韩亚洲视频_在线成人免费_欧美日韩精品免费观看视频_久草视

您的位置:首頁技術(shù)文章
文章詳情頁

使用springboot單例模式與線程安全問題踩的坑

瀏覽:129日期:2023-02-19 16:52:57
springboot單例模式與線程安全問題踩的坑

最近有客戶反映,使用公司產(chǎn)品時,偶爾會存在崩潰情況,自己測試無問題,然后去查日志,是報空指針。

于是順藤摸瓜 往上找,好嘛,之前的開發(fā)使用了成員變量,感覺問題就是在這里了,因為眾所周知,springboot 采用的是單例模式,所以,使用成員變量時一定要謹(jǐn)慎。

下面上一張該類的截圖:

使用springboot單例模式與線程安全問題踩的坑

大家可能看到了,該類上面加上了@Scope('prototype') 注解,該注解的作用是將該類變成多例模式。講道理因為變?yōu)榱硕嗬瑧?yīng)該不會有線程問題了。

我先說下我這邊的一個代碼環(huán)境,上面大家看到的BaseController這個類里面有個init方法,會在繼承它的類的所有方法前執(zhí)行。

使用springboot單例模式與線程安全問題踩的坑

使用的是@ModelAttribute注解,這個注解的意思是,在該controller的所有方法前執(zhí)行,意在初始化,我猜測之前的同事應(yīng)該是為了獲取相同的一些參數(shù),抽調(diào)出來做一個父類,隨著迭代,別的同事為了方便,拿來就用,導(dǎo)致很多controller繼承了該類。

@Scope('prototype')注解:

大家設(shè)想一下,若父類加了@Scope('prototype')注解,子類controller并沒有加該注解,會怎樣呢?該注解是否還有意義?再比如,我在某service上加上@Scope('prototype')注解,但調(diào)用的controller沒有加@Scope('prototype')注解,那么會出現(xiàn)什么樣的結(jié)果呢?大家可以去測試一下,測試方法也很簡單,就是在對應(yīng)的父類或service的無參構(gòu)造方法里打印該類的地址。

下面說下我的測試結(jié)果:

先說父類上加了@Scope('prototype')注解,子類上沒有加這種情況。結(jié)果是,同一子類繼承的為同一父類,不同子類繼承為不同父類。理解一下,很簡單,因為springboot為單例模式,所以子類為單例,那么只有一個子類,父類肯定是一樣的。所以,不同線程過來使用的為同一變量,就會有問題。

同理:

在service上標(biāo)注@Scope('prototype')注解,那在同一個controller里,該service還是同一個,也就是說還是單例的,在不同的controller里 是不同的。測試方法同上。

現(xiàn)在說下解決方法:

1、是在繼承該controller的子類上都加上@Scope('prototype')注解。這樣做的好處是簡單。壞處也同樣明顯,因為是多例的,那么就會產(chǎn)生大量的實(shí)體類,占用大量內(nèi)存,若是回收不及時,有可能會出現(xiàn)內(nèi)存溢出。

2、是將變量私有化,比如使用線程變量,對變量加鎖等,技術(shù)上會復(fù)雜一些,而且調(diào)試不太好調(diào)試。說不定那些地方就會出現(xiàn)問題,畢竟是老代碼。

3、將該類轉(zhuǎn)換為攔截器,將變量放入request里,用的時候取出來。

SpringMVC 或 SpringBoot 默認(rèn)是單例模式(Singleton)多個請求是訪問的同一個方法,是如何實(shí)現(xiàn)線程安全的?

SpringMVC Controller默認(rèn)情況下是Singleton(單例)的,當(dāng)request過來,不用每次創(chuàng)建Controller,會用原來的instance去處理。那么當(dāng)多個線程調(diào)用它的時候,會不會發(fā)生線程不安全呢?

1、先說明下 Controller默認(rèn)情況 單例的問題:

使用Spring MVC有一段時間了,之前一直使用Struts2,在struts2中action都是原型(prototype)的, 說是因為線程安全問題,對于Spring MVC中bean默認(rèn)都是(singleton)單例的,那么用@Controller注解標(biāo)簽注入的Controller類是單例實(shí)現(xiàn)的?

測試結(jié)果發(fā)現(xiàn)spring3中的controller默認(rèn)是單例的,若是某個controller中有一個私有的變量i,所有請求到同一個controller時,使用的i變量是共用的,即若是某個請求中修改了這個變量a,則,在別的請求中能夠讀到這個修改的內(nèi)容。 若是在@Controller之前增加@Scope(“prototype”),就可以改變單例模式為多例模式

以下是測試步驟,代碼與結(jié)果.

1. 如果是單例類型類的,那么在Controller類中的類變量應(yīng)該是共享的,如果不共享,就說明Controller類不是單例。

以下是測試代碼:

import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;@Controllerpublic class ExampleAction { private int singletonInt=1; @RequestMapping(value = '/test') @ResponseBody public String singleton(HttpServletRequest request, HttpServletResponse response) throws Exception { String data=request.getParameter('data'); if(data!=null&&data.length()>0){ try{ int paramInt= Integer.parseInt(data); singletonInt = singletonInt + paramInt; } catch(Exception ex){ singletonInt+=10; } }else{ singletonInt+=1000; } return String.valueOf(singletonInt); }}

分別三次請求: http://localhost:8080/example/test.do?data=15

得到的返回結(jié)果如下。

第一次: singletonInt=15

第二次: singletonInt=30

第三次: singletonInt=45

從以上結(jié)果可以得知,singletonInt的狀態(tài)是共享的,因此Controller是單例的。

2、對別Struts與springmvc對比

Struts2:默認(rèn)prototype,Struts2 是基于類的,處于線程安全的考慮,采用了prototype模式,也就是說每次請求都會新建一個類來處理,自然就沒有線程安全問題了,每次請求的類和數(shù)據(jù)都是單獨(dú)的。

Springmvc:默認(rèn)singleton 單例模式,Springmvc 是基于方法的,同一個url的請求是同一個實(shí)例處理的。每次請求都會把請求參數(shù)傳遞到同一個方法中,此時如果類里面有成員變量,那么這個變量就不是線程安全的了(例如上面的例子 private int singletonInt=1; 這個變量如果想線程安全則可以用ThreadLocal)。

在類中沒有成員變量的前提下則是線程安全的。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 亚洲精品久久久久久久久久久 | 国产精品免费一区二区三区 | 国产成人精品一区二区三区在线观看 | 久久久精品 | 欧洲精品一区二区三区 | 男女免费视频 | 中文字幕av片| 成年人午夜视频 | 成人午夜毛片 | 婷婷在线播放 | 日韩在线观看 | 亚洲成人二区 | 黄色网址在线免费观看 | 最新av在线播放 | 国产一区二区在线播放 | 欧美一区二区三区的 | 久久综合影院 | 精品国产一区二 | 九色91popny蝌蚪新疆 | 久草网在线观看 | 免费一区二区三区 | 亚洲激情五月 | 久久久国产精品人人片 | 在线观看二区 | 黄色片国产| 男女操网站 | 国产不卡在线视频 | 激情视频一区 | 天天艹夜夜艹 | 欧美精品网 | 四虎影院网站 | 一区二区三区在线观看视频 | 毛片在线免费播放 | 一区二区免费 | 性欧美精品| 日韩理论视频 | 日韩一区二区三区免费视频 | 中国极品少妇xxxx做受 | 成人一区二区在线 | 欧美日韩免费 | 制中文字幕音影 |