單例模式
作用:保證一個類只有一個實例,並且提供一個訪問該實例的全局訪問入口
1、舉栗子
1.Windows的任務管理器
2.Windows的回收站,也是一個單例應用
3.SpringMVC的控制器2、優點
1.減少了系統的性能開銷,當一個對象需要產生時,當時消耗的資源較多。那麼產生對象時構建的方式就可以通過單例去構建。
2.單例模式存在全局訪問點,所以可以優化共享資源訪問。3、常見的單例模式的構建方法
1.餓漢式:線程安全 調用率高 但是不能延遲加載
2.懶漢式:線程安全 調用率不高 但是可以延遲加載
3.雙重檢測(double check )
4.靜態內部類(線程安全 可以延遲加載)
5.枚舉單例 線程安全 不可以延遲加載
正文
SpringMVC Controller默認的是單例模式 @Scope("singleton")
採用單例模式的好處:
- 爲了性能,單例不用每次都new,當然快了。
- 不需要多例,這是官方說法。
單例模式下容易出現的問題就是controller中定義很多的屬性,那麼單例肯定會出現競爭訪問,不同用戶共享數據變量是不安全的。因此:
- 不要在controller中定義成員變量。
- 萬一必須要定義一個非靜態成員變量時候,則通過註解@Scope("prototype"),將其設置爲多例模式。
測試栗子
package com.inchlifc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @Title:
* @author: 小小漁夫
* @date:
* @Description: 測試SpringMVC單例模式
* @Company:
*/
@Controller
@RequestMapping("/hello")
public class HelloController {
private int i = 1;
@RequestMapping(value = "/test1")
public void testSingle1() {
++i;
System.out.println("test1-------"+i);
}
@RequestMapping(value = "/test2")
public void testSingle2() {
++i;
System.out.println("test2------"+i);
}
}
這裏我們新建一個Controller,定義變量i,初始化爲1.項目啓動,我們依次調用方法testSingle1()、testSingle2()再調用testSingle1()。通過結果我們會得出結論,單例模式下會共享普通成員變量和靜態成員變量。
修改代碼
package com.inchlifc.controller;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @Title:
* @author: 小小漁夫
* @date:
* @Description: 測試SpringMVC單例模式
* @Company:
*/
@Controller
@Scope("prototype")
@RequestMapping("/hello")
public class HelloController {
private int i = 1;
@RequestMapping(value = "/test1")
public void testSingle1() {
++i;
System.out.println("test1-------"+i);
}
@RequestMapping(value = "/test2")
public void testSingle2() {
++i;
System.out.println("test2------"+i);
}
}
重複上面的操作,最後我們得出的結論是多例模式下普通成員變量不共享,靜態成員共享。