SpringMVC學習筆記:單例與並發問題
阿新 • • 發佈:2018-09-11
一個 獲得 app parseint 本地服務 屬性 als min c學習
Spring中的Bean默認都是單例(singleton),Spring中Bean的scope屬性有五種類型:
- singleton 表示在spring容器中的單例,通過spring容器獲得該bean時總是返回唯一的實例
- prototype 表示每次獲得bean都會生成以新的對象
- request 表示在一次Htttp請求內有效(只適用於web應用)
- session 表示在一個用戶會話內有效(只適用於web應用)
- globalSession 表示在全局會話內有效(只適用於web應用)
SpringMVC中Controller類默認Scope是單例,因而在Controller類中使用成員變量時需要註意並發的問題,舉例說明:
@Controller public 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//test?data=15 ,得到的結果分別是15 30 45,由此說明Controller是單例
單例的好處也很明顯:不用每次創建Controller,減少了對象創建和垃圾收集的時間。
當有多個用戶同時請求一個服務時,容器會給每一個請求分配一個線程,各個線程是不會相互影響,舉例如下:
@RequestMapping(value = "/sleepdata") @ResponseBody public String switcher(HttpServletRequest request, HttpServletResponse response) throws Exception { String sleep = request.getParameter("sleep"); if (sleep.equals("on")) { Thread.currentThread().sleep(100000); return "sleep on"; } else { return sleep; } }
分別發送兩個請求,
第一個請求:http://localhost:8080/sleepdata?sleep=on
第二個請求:http://localhost:8080/sleepdata?sleep=test
驗證結果:第一個請求發出去以後,本地服務器等待100s,然後返回結果”sleep on”,在本地服務器等待的者100s當中,發送第二個請求,直接返回結果”test”。說明之間的線程是不互相影響的
單例的狀態改變:體現為該單例的成員屬性值的修改
有狀態對象(Stateful Bean):就是有成員變量的對象,可以保存數據,是非線程安全的
無狀態對象(Stateless Bean):就是沒有實例變量的對象,不能保存數據,是不變類,是線程安全的
Spring對一些Bean中非線程安全狀態采用ThreadLocal進行處理,讓它們也成為線程安全的狀態
內容來源網絡,非原創,侵刪
SpringMVC學習筆記:單例與並發問題