咱們在@RestController下,通常都是@AutoWired一些Service,因爲這些Service都是單例,對於在Controller中調用他們的方法,因爲方法在JVM中屬於棧操做,對於每個線程來講,棧都是獨立的,因此是線程安全的。 因爲Controller自己是單例模式 (非線程安全的), 這意味着每一個request過來,系統都會用原有的instance去處理,這樣致使了兩個結果:一是咱們不用每次建立Controller,二是減小了對象建立和垃圾收集的時間;因爲只有一個Controller的instance,當多個線程調用它的時候,它裏面的instance變量就不是線程安全的了,會發生竄數據的問題。 若是咱們定義了一個類的實例,如 private Company company = new Company(); 而在@RequestMapping方法中去用到了他, 這裏就存在併發線程安全的問題。對於全部的請求request,這個company對象是相通的。 固然咱們也能夠用這個特性來製做訪問計數器 只須要定義一個private int cout = 0; 在每一次請求後cout++;redis
固然我並不推薦這麼作,計數器最好用redis來操做。安全
總結以上問題,不要在Controller裏出現類的實例。即使加了線程安全操做,也會出現性能問題。固然不管是Controller仍是Service,若是你必定要使用對象的屬性,如private Company company = new Company();能夠加上ThreadLocal的引用,如private ThreadLocal<Company> tc = new ThreadLocal<>();可是把這種使用的對象放進方法中初始化(即進入JVM棧中更好)。併發